mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-03 03:10:47 +00:00
no message
This commit is contained in:
parent
99883e6998
commit
3da3ebe3e2
@ -17,8 +17,8 @@
|
||||
D0079F631D5A242500A27A2C /* ContactPeerIdsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F621D5A242500A27A2C /* ContactPeerIdsView.swift */; };
|
||||
D0079F651D5A457A00A27A2C /* ContactPeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F641D5A457A00A27A2C /* ContactPeersView.swift */; };
|
||||
D0079F6B1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F6A1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift */; };
|
||||
D00C7CD41E365C4E0080C3D5 /* PeerChatListPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD31E365C4E0080C3D5 /* PeerChatListPolicy.swift */; };
|
||||
D00C7CD51E365C4E0080C3D5 /* PeerChatListPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD31E365C4E0080C3D5 /* PeerChatListPolicy.swift */; };
|
||||
D00C7CD41E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD31E365C4E0080C3D5 /* PeerChatListInclusion.swift */; };
|
||||
D00C7CD51E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CD31E365C4E0080C3D5 /* PeerChatListInclusion.swift */; };
|
||||
D00C7CE31E37861C0080C3D5 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CE21E37861C0080C3D5 /* MessageView.swift */; };
|
||||
D00C7CE41E37861C0080C3D5 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00C7CE21E37861C0080C3D5 /* MessageView.swift */; };
|
||||
D00EED1E1C81F28D00341DFF /* MessageHistoryTagsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00EED1D1C81F28D00341DFF /* MessageHistoryTagsTable.swift */; };
|
||||
@ -75,6 +75,12 @@
|
||||
D07CFF811DCA765D00761F81 /* PeerChatInterfaceState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07CFF801DCA765D00761F81 /* PeerChatInterfaceState.swift */; };
|
||||
D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07CFF821DCA909100761F81 /* PeerChatInterfaceStateTable.swift */; };
|
||||
D07CFF851DCA99C400761F81 /* InitialMessageHistoryData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07CFF841DCA99C400761F81 /* InitialMessageHistoryData.swift */; };
|
||||
D08775001E3E3D9F00A97350 /* PreferencesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FF1E3E3D9F00A97350 /* PreferencesTable.swift */; };
|
||||
D08775011E3E3D9F00A97350 /* PreferencesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FF1E3E3D9F00A97350 /* PreferencesTable.swift */; };
|
||||
D08775031E3E3E7400A97350 /* PreferencesEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08775021E3E3E7400A97350 /* PreferencesEntry.swift */; };
|
||||
D08775041E3E3E7400A97350 /* PreferencesEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08775021E3E3E7400A97350 /* PreferencesEntry.swift */; };
|
||||
D08775061E3E3F2100A97350 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08775051E3E3F2100A97350 /* PreferencesView.swift */; };
|
||||
D08775071E3E3F2100A97350 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08775051E3E3F2100A97350 /* PreferencesView.swift */; };
|
||||
D08C713A1C501F0700779C0F /* MessageHistoryHole.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08C71391C501F0700779C0F /* MessageHistoryHole.swift */; };
|
||||
D08C713C1C51283C00779C0F /* MessageHistoryIndexTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08C713B1C51283C00779C0F /* MessageHistoryIndexTable.swift */; };
|
||||
D08C713E1C512EA500779C0F /* MessageHistoryTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08C713D1C512EA500779C0F /* MessageHistoryTable.swift */; };
|
||||
@ -138,6 +144,7 @@
|
||||
D0B844071DAB91B5005F29E1 /* MediaResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CE63F51CA1CCB2002BC462 /* MediaResource.swift */; };
|
||||
D0B8440A1DAB91B5005F29E1 /* RandomAccessMediaResourceContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09ADF091D2E89F300C8208D /* RandomAccessMediaResourceContext.swift */; };
|
||||
D0B844511DAC04FE005F29E1 /* PeerPresence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B844501DAC04FE005F29E1 /* PeerPresence.swift */; };
|
||||
D0BC386C1E3FCEE50044D6FE /* MultiplePeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC386B1E3FCEE50044D6FE /* MultiplePeersView.swift */; };
|
||||
D0C07F6A1B67DB4800966E43 /* SwiftSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */; };
|
||||
D0C674C81CBB11C600183765 /* MessageHistoryReadStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674C71CBB11C600183765 /* MessageHistoryReadStateTable.swift */; };
|
||||
D0C674CC1CBB14A700183765 /* PeerReadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C674CB1CBB14A700183765 /* PeerReadState.swift */; };
|
||||
@ -230,7 +237,7 @@
|
||||
D0079F621D5A242500A27A2C /* ContactPeerIdsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactPeerIdsView.swift; sourceTree = "<group>"; };
|
||||
D0079F641D5A457A00A27A2C /* ContactPeersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactPeersView.swift; sourceTree = "<group>"; };
|
||||
D0079F6A1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerNameIndexRepresentation.swift; sourceTree = "<group>"; };
|
||||
D00C7CD31E365C4E0080C3D5 /* PeerChatListPolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatListPolicy.swift; sourceTree = "<group>"; };
|
||||
D00C7CD31E365C4E0080C3D5 /* PeerChatListInclusion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatListInclusion.swift; sourceTree = "<group>"; };
|
||||
D00C7CE21E37861C0080C3D5 /* MessageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageView.swift; sourceTree = "<group>"; };
|
||||
D00EED1D1C81F28D00341DFF /* MessageHistoryTagsTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryTagsTable.swift; sourceTree = "<group>"; };
|
||||
D010B6191E1E463900C3E282 /* PeerMergedOperationLogIndexTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMergedOperationLogIndexTable.swift; sourceTree = "<group>"; };
|
||||
@ -272,6 +279,9 @@
|
||||
D07CFF801DCA765D00761F81 /* PeerChatInterfaceState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatInterfaceState.swift; sourceTree = "<group>"; };
|
||||
D07CFF821DCA909100761F81 /* PeerChatInterfaceStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatInterfaceStateTable.swift; sourceTree = "<group>"; };
|
||||
D07CFF841DCA99C400761F81 /* InitialMessageHistoryData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitialMessageHistoryData.swift; sourceTree = "<group>"; };
|
||||
D08774FF1E3E3D9F00A97350 /* PreferencesTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesTable.swift; sourceTree = "<group>"; };
|
||||
D08775021E3E3E7400A97350 /* PreferencesEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesEntry.swift; sourceTree = "<group>"; };
|
||||
D08775051E3E3F2100A97350 /* PreferencesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
|
||||
D08C71391C501F0700779C0F /* MessageHistoryHole.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryHole.swift; sourceTree = "<group>"; };
|
||||
D08C713B1C51283C00779C0F /* MessageHistoryIndexTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryIndexTable.swift; sourceTree = "<group>"; };
|
||||
D08C713D1C512EA500779C0F /* MessageHistoryTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryTable.swift; sourceTree = "<group>"; };
|
||||
@ -298,6 +308,7 @@
|
||||
D0B418161D7DFAF3004562A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D0B418601D7DFE95004562A4 /* SwiftSignalKitMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftSignalKitMac.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegram-iOS-diblohvjozhgaifjcniwdlixlilx/Build/Products/Debug/SwiftSignalKitMac.framework"; sourceTree = "<group>"; };
|
||||
D0B844501DAC04FE005F29E1 /* PeerPresence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerPresence.swift; sourceTree = "<group>"; };
|
||||
D0BC386B1E3FCEE50044D6FE /* MultiplePeersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultiplePeersView.swift; sourceTree = "<group>"; };
|
||||
D0C07F691B67DB4800966E43 /* SwiftSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SwiftSignalKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
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>"; };
|
||||
@ -470,6 +481,7 @@
|
||||
D0AD23281E196B6400A7089A /* PeerOperationLogMetadataTable.swift */,
|
||||
D0AAD1B11E3266B100D5B9DE /* TimestampBasedMessageAttributesTable.swift */,
|
||||
D0AAD1B01E3266B100D5B9DE /* TimestampBasedMessageAttributesIndexTable.swift */,
|
||||
D08774FF1E3E3D9F00A97350 /* PreferencesTable.swift */,
|
||||
);
|
||||
name = Tables;
|
||||
sourceTree = "<group>";
|
||||
@ -490,7 +502,8 @@
|
||||
D03120FB1DA55427006A2A60 /* PeerNotificationSettings.swift */,
|
||||
D021E0D31DB4FAE100C6B04F /* ItemCollection.swift */,
|
||||
D07CFF801DCA765D00761F81 /* PeerChatInterfaceState.swift */,
|
||||
D00C7CD31E365C4E0080C3D5 /* PeerChatListPolicy.swift */,
|
||||
D00C7CD31E365C4E0080C3D5 /* PeerChatListInclusion.swift */,
|
||||
D08775021E3E3E7400A97350 /* PreferencesEntry.swift */,
|
||||
);
|
||||
name = Objects;
|
||||
sourceTree = "<group>";
|
||||
@ -538,6 +551,8 @@
|
||||
D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift */,
|
||||
D0AAD1B41E32673C00D5B9DE /* TimestampBasedMessageAttributesView.swift */,
|
||||
D00C7CE21E37861C0080C3D5 /* MessageView.swift */,
|
||||
D08775051E3E3F2100A97350 /* PreferencesView.swift */,
|
||||
D0BC386B1E3FCEE50044D6FE /* MultiplePeersView.swift */,
|
||||
);
|
||||
name = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -811,6 +826,7 @@
|
||||
D0B418271D7DFE0C004562A4 /* IpcPipe.swift in Sources */,
|
||||
D0B4184D1D7DFE20004562A4 /* ContactPeersView.swift in Sources */,
|
||||
D00C7CE41E37861C0080C3D5 /* MessageView.swift in Sources */,
|
||||
D08775011E3E3D9F00A97350 /* PreferencesTable.swift in Sources */,
|
||||
D0F7B1CC1E045C6A007EB8A5 /* ChatListIndexTable.swift in Sources */,
|
||||
D0B4185E1D7DFE54004562A4 /* IpcNotifier.mm in Sources */,
|
||||
D0F7B1D31E045C6A007EB8A5 /* CachedPeerDataTable.swift in Sources */,
|
||||
@ -818,6 +834,7 @@
|
||||
D0F7B1D51E045C6A007EB8A5 /* PeerChatStateTable.swift in Sources */,
|
||||
D0F7B1C51E045C6A007EB8A5 /* MessageHistoryMetadataTable.swift in Sources */,
|
||||
D073CE781DCBF3B4007511FD /* MessageHistoryHole.swift in Sources */,
|
||||
D08775071E3E3F2100A97350 /* PreferencesView.swift in Sources */,
|
||||
D0AAD1B61E32673C00D5B9DE /* TimestampBasedMessageAttributesView.swift in Sources */,
|
||||
D0F7B1C31E045C6A007EB8A5 /* Table.swift in Sources */,
|
||||
D0F7B1CF1E045C6A007EB8A5 /* MetadataTable.swift in Sources */,
|
||||
@ -850,7 +867,7 @@
|
||||
D073CE7D1DCBF3B4007511FD /* PeerPresence.swift in Sources */,
|
||||
D0B4184C1D7DFE20004562A4 /* ContactPeerIdsView.swift in Sources */,
|
||||
D073CE751DCBF3B4007511FD /* Message.swift in Sources */,
|
||||
D00C7CD51E365C4E0080C3D5 /* PeerChatListPolicy.swift in Sources */,
|
||||
D00C7CD51E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */,
|
||||
D0F7B1CB1E045C6A007EB8A5 /* ChatListTable.swift in Sources */,
|
||||
D0F7B1C01E045C62007EB8A5 /* StringIndexTokens.swift in Sources */,
|
||||
D0F7B1CA1E045C6A007EB8A5 /* MessageHistoryUnsentTable.swift in Sources */,
|
||||
@ -860,6 +877,7 @@
|
||||
D0B8440A1DAB91B5005F29E1 /* RandomAccessMediaResourceContext.swift in Sources */,
|
||||
D0B418581D7DFE29004562A4 /* SeedConfiguration.swift in Sources */,
|
||||
D0B418311D7DFE16004562A4 /* ValueBox.swift in Sources */,
|
||||
D08775041E3E3E7400A97350 /* PreferencesEntry.swift in Sources */,
|
||||
D0B4184E1D7DFE20004562A4 /* MessageHistoryHolesView.swift in Sources */,
|
||||
D0B844051DAB91B5005F29E1 /* MediaBox.swift in Sources */,
|
||||
D0B418321D7DFE16004562A4 /* SqliteValueBox.swift in Sources */,
|
||||
@ -878,6 +896,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D08775061E3E3F2100A97350 /* PreferencesView.swift in Sources */,
|
||||
D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */,
|
||||
D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */,
|
||||
D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */,
|
||||
@ -937,10 +956,11 @@
|
||||
D0F019FD1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift in Sources */,
|
||||
D0F9E8651C58CB7F00037222 /* ChatListTable.swift in Sources */,
|
||||
D0F9E8711C5A0E9B00037222 /* PeerTable.swift in Sources */,
|
||||
D0BC386C1E3FCEE50044D6FE /* MultiplePeersView.swift in Sources */,
|
||||
D07CFF851DCA99C400761F81 /* InitialMessageHistoryData.swift in Sources */,
|
||||
D05F09A61C9E9F9300BB6F96 /* MediaResourceStatus.swift in Sources */,
|
||||
D033A6F71C73D512006A2EAB /* MessageHistoryUnsentTable.swift in Sources */,
|
||||
D00C7CD41E365C4E0080C3D5 /* PeerChatListPolicy.swift in Sources */,
|
||||
D00C7CD41E365C4E0080C3D5 /* PeerChatListInclusion.swift in Sources */,
|
||||
D0A18D671E16874D004C6734 /* UnreadMessageCountsView.swift in Sources */,
|
||||
D0D511021D64D73D00A97B8A /* IpcNotifier.mm in Sources */,
|
||||
D0B844511DAC04FE005F29E1 /* PeerPresence.swift in Sources */,
|
||||
@ -951,7 +971,9 @@
|
||||
D0F9E86D1C5A0E5D00037222 /* MetadataTable.swift in Sources */,
|
||||
D0E3A7841B28AE0900A402D9 /* Peer.swift in Sources */,
|
||||
D0D510F61D63BBE100A97B8A /* MessageHistoryOperation.swift in Sources */,
|
||||
D08775031E3E3E7400A97350 /* PreferencesEntry.swift in Sources */,
|
||||
D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */,
|
||||
D08775001E3E3D9F00A97350 /* PreferencesTable.swift in Sources */,
|
||||
D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */,
|
||||
D0F9E8731C5A1EE500037222 /* GlobalMessageIdsTable.swift in Sources */,
|
||||
D00EED1E1C81F28D00341DFF /* MessageHistoryTagsTable.swift in Sources */,
|
||||
|
@ -1,14 +1,12 @@
|
||||
import Foundation
|
||||
|
||||
final class MutableContactPeersView {
|
||||
fileprivate let index: PeerNameIndex
|
||||
fileprivate var peers: [PeerId: Peer]
|
||||
fileprivate var peerPresences: [PeerId: PeerPresence]
|
||||
fileprivate var peerIds: Set<PeerId>
|
||||
fileprivate var accountPeer: Peer?
|
||||
|
||||
init(peers: [PeerId: Peer], peerPresences: [PeerId: PeerPresence], index: PeerNameIndex, accountPeer: Peer?) {
|
||||
self.index = index
|
||||
init(peers: [PeerId: Peer], peerPresences: [PeerId: PeerPresence], accountPeer: Peer?) {
|
||||
self.peers = peers
|
||||
self.peerIds = Set<PeerId>(peers.map { $0.0 })
|
||||
self.peerPresences = peerPresences
|
||||
@ -59,7 +57,6 @@ public final class ContactPeersView {
|
||||
public let accountPeer: Peer?
|
||||
|
||||
init(_ mutableView: MutableContactPeersView) {
|
||||
let index = mutableView.index
|
||||
if let accountPeer = mutableView.accountPeer {
|
||||
var peers: [Peer] = []
|
||||
peers.reserveCapacity(mutableView.peers.count)
|
||||
|
52
Postbox/MultiplePeersView.swift
Normal file
52
Postbox/MultiplePeersView.swift
Normal file
@ -0,0 +1,52 @@
|
||||
import Foundation
|
||||
|
||||
final class MutableMultiplePeersView {
|
||||
let peerIds: Set<PeerId>
|
||||
|
||||
var peers: [PeerId: Peer] = [:]
|
||||
var presences: [PeerId: PeerPresence] = [:]
|
||||
|
||||
init(peerIds: [PeerId], getPeer: (PeerId) -> Peer?, getPeerPresence: (PeerId) -> PeerPresence?) {
|
||||
self.peerIds = Set(peerIds)
|
||||
|
||||
for peerId in self.peerIds {
|
||||
if let peer = getPeer(peerId) {
|
||||
self.peers[peerId] = peer
|
||||
}
|
||||
if let presence = getPeerPresence(peerId) {
|
||||
self.presences[peerId] = presence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func replay(updatedPeers: [PeerId: Peer], updatedPeerPresences: [PeerId: PeerPresence]) -> Bool {
|
||||
if updatedPeers.isEmpty && updatedPeerPresences.isEmpty {
|
||||
return false
|
||||
}
|
||||
|
||||
var updated = false
|
||||
|
||||
for peerId in self.peerIds {
|
||||
if let peer = updatedPeers[peerId] {
|
||||
self.peers[peerId] = peer
|
||||
updated = true
|
||||
}
|
||||
if let presence = updatedPeerPresences[peerId] {
|
||||
self.presences[peerId] = presence
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
|
||||
return updated
|
||||
}
|
||||
}
|
||||
|
||||
public final class MultiplePeersView {
|
||||
public let peers: [PeerId: Peer]
|
||||
public let presences: [PeerId: PeerPresence]
|
||||
|
||||
init(_ view: MutableMultiplePeersView) {
|
||||
self.peers = view.peers
|
||||
self.presences = view.presences
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@ import Foundation
|
||||
|
||||
public enum PeerChatListInclusion {
|
||||
case never
|
||||
case ifNotEmpty
|
||||
case ifHasMessages
|
||||
case always(minTimestamp: Int32)
|
||||
}
|
@ -66,6 +66,28 @@ final class PeerNotificationSettingsTable: Table {
|
||||
return (added, removed)
|
||||
}
|
||||
|
||||
func resetAll(to settings: PeerNotificationSettings) -> [PeerId] {
|
||||
let lowerBound = ValueBoxKey(length: 8)
|
||||
lowerBound.setInt64(0, value: 0)
|
||||
let upperBound = ValueBoxKey(length: 8)
|
||||
upperBound.setInt64(0, value: Int64.max)
|
||||
var peerIds: [PeerId] = []
|
||||
self.valueBox.range(self.table, start: lowerBound, end: upperBound, keys: { key in
|
||||
peerIds.append(PeerId(key.getInt64(0)))
|
||||
return true
|
||||
}, limit: 0)
|
||||
|
||||
var updatedPeerIds: [PeerId] = []
|
||||
for peerId in peerIds {
|
||||
if let current = self.get(peerId), !current.isEqual(to: settings) {
|
||||
updatedPeerIds.append(peerId)
|
||||
self.set(id: peerId, settings: settings)
|
||||
}
|
||||
}
|
||||
|
||||
return updatedPeerIds
|
||||
}
|
||||
|
||||
override func beforeCommit() {
|
||||
if !self.updatedInitialSettings.isEmpty {
|
||||
for (peerId, _) in self.updatedInitialSettings {
|
||||
|
@ -134,6 +134,10 @@ public final class Modifier {
|
||||
self.postbox?.updatePeerNotificationSettings(notificationSettings)
|
||||
}
|
||||
|
||||
public func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) {
|
||||
self.postbox?.resetAllPeerNotificationSettings(notificationSettings)
|
||||
}
|
||||
|
||||
public func updatePeerCachedData(peerIds: Set<PeerId>, update: (PeerId, CachedPeerData?) -> CachedPeerData?) {
|
||||
self.postbox?.updatePeerCachedData(peerIds: peerIds, update: update)
|
||||
}
|
||||
@ -241,6 +245,18 @@ public final class Modifier {
|
||||
public func removeTimestampBasedMessageAttribute(tag: UInt16, messageId: MessageId) {
|
||||
self.postbox?.removeTimestampBasedMessageAttribute(tag: tag, messageId: messageId)
|
||||
}
|
||||
|
||||
public func getPreferencesEntry(key: ValueBoxKey) -> PreferencesEntry? {
|
||||
return self.postbox?.getPreferencesEntry(key: key)
|
||||
}
|
||||
|
||||
public func setPreferencesEntry(key: ValueBoxKey, value: PreferencesEntry?) {
|
||||
self.postbox?.setPreferencesEntry(key: key, value: value)
|
||||
}
|
||||
|
||||
public func updatePreferencesEntry(key: ValueBoxKey, _ f: (PreferencesEntry?) -> PreferencesEntry?) {
|
||||
self.postbox?.setPreferencesEntry(key: key, value: f(self.postbox?.getPreferencesEntry(key: key)))
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate class PipeNotifier: NSObject {
|
||||
@ -295,6 +311,7 @@ public final class Postbox {
|
||||
private var currentUpdatedTotalUnreadCount: Int32?
|
||||
private var currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation] = []
|
||||
private var currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation] = []
|
||||
private var currentPreferencesOperations: [PreferencesOperation] = []
|
||||
|
||||
private var currentReplaceChatListHoles: [(MessageIndex, ChatListHole?)] = []
|
||||
private var currentReplacedContactPeerIds: Set<PeerId>?
|
||||
@ -346,6 +363,7 @@ public final class Postbox {
|
||||
var peerOperationLogTable: PeerOperationLogTable!
|
||||
var timestampBasedMessageAttributesTable: TimestampBasedMessageAttributesTable!
|
||||
var timestampBasedMessageAttributesIndexTable: TimestampBasedMessageAttributesIndexTable!
|
||||
var preferencesTable: PreferencesTable!
|
||||
|
||||
//temporary
|
||||
var peerRatingTable: RatingTable<PeerId>!
|
||||
@ -363,14 +381,14 @@ public final class Postbox {
|
||||
self.mediaBox = MediaBox(basePath: self.basePath + "/media")
|
||||
|
||||
self.pipeNotifier = PipeNotifier(basePath: basePath, notify: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
//if let strongSelf = self {
|
||||
/*strongSelf.queue.async {
|
||||
if strongSelf.valueBox != nil {
|
||||
let _ = strongSelf.modify({ _ -> Void in
|
||||
}).start()
|
||||
}
|
||||
}*/
|
||||
}
|
||||
//}
|
||||
})
|
||||
|
||||
self.openDatabase()
|
||||
@ -468,6 +486,7 @@ public final class Postbox {
|
||||
self.peerOperationLogMetadataTable = PeerOperationLogMetadataTable(valueBox: self.valueBox, table: PeerOperationLogMetadataTable.tableSpec(29))
|
||||
self.peerMergedOperationLogIndexTable = PeerMergedOperationLogIndexTable(valueBox: self.valueBox, table: PeerMergedOperationLogIndexTable.tableSpec(30), metadataTable: self.peerOperationLogMetadataTable!)
|
||||
self.peerOperationLogTable = PeerOperationLogTable(valueBox: self.valueBox, table: PeerOperationLogTable.tableSpec(31), metadataTable: self.peerOperationLogMetadataTable, mergedIndexTable: self.peerMergedOperationLogIndexTable)
|
||||
self.preferencesTable = PreferencesTable(valueBox: self.valueBox, table: PreferencesTable.tableSpec(35))
|
||||
|
||||
self.tables.append(self.keychainTable)
|
||||
self.tables.append(self.peerTable)
|
||||
@ -500,6 +519,7 @@ public final class Postbox {
|
||||
self.tables.append(self.peerOperationLogMetadataTable)
|
||||
self.tables.append(self.peerMergedOperationLogIndexTable)
|
||||
self.tables.append(self.peerOperationLogTable)
|
||||
self.tables.append(self.preferencesTable)
|
||||
|
||||
self.transactionStateVersion = self.metadataTable.transactionStateVersion()
|
||||
|
||||
@ -521,6 +541,8 @@ public final class Postbox {
|
||||
return self.peerMergedOperationLogIndexTable.tailIndex(tag: tag)
|
||||
}, getTimestampBasedMessageAttributesHead: { tag in
|
||||
return self.timestampBasedMessageAttributesTable.head(tag: tag)
|
||||
}, getPreferencesEntry: { key in
|
||||
return self.preferencesTable.get(key: key)
|
||||
}, unsentMessageIds: self.messageHistoryUnsentTable!.get(), synchronizePeerReadStateOperations: self.synchronizeReadStateTable!.get(getCombinedPeerReadState: { peerId in
|
||||
return self.readStateTable.getCombinedState(peerId)
|
||||
}))
|
||||
@ -942,7 +964,7 @@ public final class Postbox {
|
||||
return self.peerTable.get(peerId)
|
||||
}, updatedTotalUnreadCount: &self.currentUpdatedTotalUnreadCount)
|
||||
|
||||
let transaction = PostboxTransaction(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, updatedMedia: self.currentUpdatedMedia, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentUpdatedMasterClientId: currentUpdatedMasterClientId)
|
||||
let transaction = PostboxTransaction(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, updatedMedia: self.currentUpdatedMedia, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentUpdatedMasterClientId: currentUpdatedMasterClientId)
|
||||
var updatedTransactionState: Int64?
|
||||
var updatedMasterClientId: Int64?
|
||||
if !transaction.isEmpty {
|
||||
@ -973,6 +995,7 @@ public final class Postbox {
|
||||
self.currentUpdatedTotalUnreadCount = nil
|
||||
self.currentPeerMergedOperationLogOperations.removeAll()
|
||||
self.currentTimestampBasedMessageAttributesOperations.removeAll()
|
||||
self.currentPreferencesOperations.removeAll()
|
||||
|
||||
for table in self.tables {
|
||||
table.beforeCommit()
|
||||
@ -1022,6 +1045,12 @@ public final class Postbox {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func resetAllPeerNotificationSettings(_ notificationSettings: PeerNotificationSettings) {
|
||||
for peerId in self.peerNotificationSettingsTable.resetAll(to: notificationSettings) {
|
||||
self.currentUpdatedPeerNotificationSettings[peerId] = notificationSettings
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func updatePeerCachedData(peerIds: Set<PeerId>, update: (PeerId, CachedPeerData?) -> CachedPeerData?) {
|
||||
for peerId in peerIds {
|
||||
let currentData = self.cachedPeerDataTable.get(peerId)
|
||||
@ -1166,7 +1195,7 @@ public final class Postbox {
|
||||
private func addLocationsToMessageHistoryViewEntries(tagMask: MessageTags, earlier: MutableMessageHistoryEntry?, later: MutableMessageHistoryEntry?, entries: [MutableMessageHistoryEntry]) -> ([MutableMessageHistoryEntry], MutableMessageHistoryEntry?, MutableMessageHistoryEntry?) {
|
||||
if let firstEntry = entries.first {
|
||||
if let location = self.messageHistoryTagsTable.entryLocation(at: firstEntry.index, tagMask: tagMask) {
|
||||
var mappedEarlier = earlier?.updatedLocation(location.predecessor)
|
||||
let mappedEarlier = earlier?.updatedLocation(location.predecessor)
|
||||
var mappedEntries: [MutableMessageHistoryEntry] = []
|
||||
var previousLocation: MessageHistoryEntryLocation?
|
||||
for i in 0 ..< entries.count {
|
||||
@ -1179,7 +1208,7 @@ public final class Postbox {
|
||||
}
|
||||
}
|
||||
previousLocation = previousLocation?.successor
|
||||
var mappedLater = later?.updatedLocation(previousLocation)
|
||||
let mappedLater = later?.updatedLocation(previousLocation)
|
||||
return (mappedEntries, mappedEarlier, mappedLater)
|
||||
} else {
|
||||
return (entries, earlier, later)
|
||||
@ -1333,7 +1362,7 @@ public final class Postbox {
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public func contactPeersView(index: PeerNameIndex, accountPeerId: PeerId) -> Signal<ContactPeersView, NoError> {
|
||||
public func contactPeersView(accountPeerId: PeerId) -> Signal<ContactPeersView, NoError> {
|
||||
return self.modify { modifier -> Signal<ContactPeersView, NoError> in
|
||||
var peers: [PeerId: Peer] = [:]
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
@ -1347,7 +1376,7 @@ public final class Postbox {
|
||||
}
|
||||
}
|
||||
|
||||
let view = MutableContactPeersView(peers: peers, peerPresences: peerPresences, index: index, accountPeer: self.peerTable.get(accountPeerId))
|
||||
let view = MutableContactPeersView(peers: peers, peerPresences: peerPresences, accountPeer: self.peerTable.get(accountPeerId))
|
||||
let (index, signal) = self.viewTracker.addContactPeersView(view)
|
||||
|
||||
return (.single(ContactPeersView(view))
|
||||
@ -1424,6 +1453,23 @@ public final class Postbox {
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public func multiplePeersView(_ ids: [PeerId]) -> Signal<MultiplePeersView, NoError> {
|
||||
return self.modify { modifier -> Signal<MultiplePeersView, NoError> in
|
||||
let view = MutableMultiplePeersView(peerIds: ids, getPeer: { self.peerTable.get($0) }, getPeerPresence: { self.peerPresenceTable.get($0) })
|
||||
let (index, signal) = self.viewTracker.addMultiplePeersView(view)
|
||||
|
||||
return (.single(MultiplePeersView(view))
|
||||
|> then(signal))
|
||||
|> afterDisposed { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.queue.async {
|
||||
strongSelf.viewTracker.removeMultiplePeersView(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public func loadedPeerWithId(_ id: PeerId) -> Signal<Peer, NoError> {
|
||||
return self.modify { modifier -> Signal<Peer, NoError> in
|
||||
if let peer = self.peerTable.get(id) {
|
||||
@ -1464,7 +1510,7 @@ public final class Postbox {
|
||||
}
|
||||
|
||||
public func updateMessageHistoryViewVisibleRange(_ id: MessageHistoryViewId, earliestVisibleIndex: MessageIndex, latestVisibleIndex: MessageIndex) {
|
||||
self.modify({ modifier -> Void in
|
||||
let _ = self.modify({ modifier -> Void in
|
||||
self.viewTracker.updateMessageHistoryViewVisibleRange(id, earliestVisibleIndex: earliestVisibleIndex, latestVisibleIndex: latestVisibleIndex)
|
||||
}).start()
|
||||
}
|
||||
@ -1640,6 +1686,33 @@ public final class Postbox {
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public func preferencesView(keys: [ValueBoxKey]) -> Signal<PreferencesView, NoError> {
|
||||
return self.modify { modifier -> Signal<PreferencesView, NoError> in
|
||||
let view = MutablePreferencesView(keys: Set(keys), get: { key in
|
||||
return self.preferencesTable.get(key: key)
|
||||
})
|
||||
let (index, signal) = self.viewTracker.addPreferencesView(view)
|
||||
|
||||
return (.single(PreferencesView(view))
|
||||
|> then(signal))
|
||||
|> afterDisposed { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.queue.async {
|
||||
strongSelf.viewTracker.removePreferencesView(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
fileprivate func getPreferencesEntry(key: ValueBoxKey) -> PreferencesEntry? {
|
||||
return self.preferencesTable.get(key: key)
|
||||
}
|
||||
|
||||
fileprivate func setPreferencesEntry(key: ValueBoxKey, value: PreferencesEntry?) {
|
||||
self.preferencesTable.set(key: key, value: value, operations: &self.currentPreferencesOperations)
|
||||
}
|
||||
|
||||
public func isMasterClient() -> Signal<Bool, NoError> {
|
||||
return self.modify { modifier -> Signal<Bool, NoError> in
|
||||
let sessionClientId = self.sessionClientId
|
||||
@ -1650,7 +1723,7 @@ public final class Postbox {
|
||||
}
|
||||
|
||||
public func becomeMasterClient() {
|
||||
self.modify({ modifier in
|
||||
let _ = self.modify({ modifier in
|
||||
if self.metadataTable.masterClientId() != self.sessionClientId {
|
||||
self.currentUpdatedMasterClientId = self.sessionClientId
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ final class PostboxTransaction {
|
||||
let peerIdsWithUpdatedUnreadCounts: Set<PeerId>
|
||||
let currentPeerMergedOperationLogOperations: [PeerMergedOperationLogOperation]
|
||||
let currentTimestampBasedMessageAttributesOperations: [TimestampBasedMessageAttributesOperation]
|
||||
let currentPreferencesOperations: [PreferencesOperation]
|
||||
|
||||
let unsentMessageOperations: [IntermediateMessageHistoryUnsentOperation]
|
||||
let updatedSynchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation?]
|
||||
@ -76,10 +77,13 @@ final class PostboxTransaction {
|
||||
if !currentTimestampBasedMessageAttributesOperations.isEmpty {
|
||||
return false
|
||||
}
|
||||
if !currentPreferencesOperations.isEmpty {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
init(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?], updatedMedia: [MediaId: Media?], replaceContactPeerIds: Set<PeerId>?, currentUpdatedMasterClientId: Int64?) {
|
||||
init(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], updatedMedia: [MediaId: Media?], replaceContactPeerIds: Set<PeerId>?, currentUpdatedMasterClientId: Int64?) {
|
||||
self.currentOperationsByPeerId = currentOperationsByPeerId
|
||||
self.peerIdsWithFilledHoles = peerIdsWithFilledHoles
|
||||
self.removedHolesByPeerId = removedHolesByPeerId
|
||||
@ -95,6 +99,7 @@ final class PostboxTransaction {
|
||||
self.currentTimestampBasedMessageAttributesOperations = currentTimestampBasedMessageAttributesOperations
|
||||
self.unsentMessageOperations = unsentMessageOperations
|
||||
self.updatedSynchronizePeerReadStateOperations = updatedSynchronizePeerReadStateOperations
|
||||
self.currentPreferencesOperations = currentPreferencesOperations
|
||||
self.updatedMedia = updatedMedia
|
||||
self.replaceContactPeerIds = replaceContactPeerIds
|
||||
self.currentUpdatedMasterClientId = currentUpdatedMasterClientId
|
||||
|
5
Postbox/PreferencesEntry.swift
Normal file
5
Postbox/PreferencesEntry.swift
Normal file
@ -0,0 +1,5 @@
|
||||
import Foundation
|
||||
|
||||
public protocol PreferencesEntry: Coding {
|
||||
func isEqual(to: PreferencesEntry) -> Bool
|
||||
}
|
58
Postbox/PreferencesTable.swift
Normal file
58
Postbox/PreferencesTable.swift
Normal file
@ -0,0 +1,58 @@
|
||||
import Foundation
|
||||
|
||||
enum PreferencesOperation {
|
||||
case update(ValueBoxKey, PreferencesEntry?)
|
||||
}
|
||||
|
||||
private struct CachedEntry {
|
||||
let entry: PreferencesEntry?
|
||||
}
|
||||
|
||||
final class PreferencesTable: Table {
|
||||
private var cachedEntries: [ValueBoxKey: CachedEntry] = [:]
|
||||
private var updatedEntryKeys = Set<ValueBoxKey>()
|
||||
|
||||
static func tableSpec(_ id: Int32) -> ValueBoxTable {
|
||||
return ValueBoxTable(id: id, keyType: .binary)
|
||||
}
|
||||
|
||||
func get(key: ValueBoxKey) -> PreferencesEntry? {
|
||||
if let cached = self.cachedEntries[key] {
|
||||
return cached.entry
|
||||
} else {
|
||||
if let value = self.valueBox.get(self.table, key: key), let object = Decoder(buffer: value).decodeRootObject() as? PreferencesEntry {
|
||||
self.cachedEntries[key] = CachedEntry(entry: object)
|
||||
return object
|
||||
} else {
|
||||
self.cachedEntries[key] = CachedEntry(entry: nil)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func set(key: ValueBoxKey, value: PreferencesEntry?, operations: inout [PreferencesOperation]) {
|
||||
self.cachedEntries[key] = CachedEntry(entry: value)
|
||||
updatedEntryKeys.insert(key)
|
||||
operations.append(.update(key, value))
|
||||
}
|
||||
|
||||
override func clearMemoryCache() {
|
||||
assert(self.updatedEntryKeys.isEmpty)
|
||||
}
|
||||
|
||||
override func beforeCommit() {
|
||||
if !self.updatedEntryKeys.isEmpty {
|
||||
for key in self.updatedEntryKeys {
|
||||
if let value = self.cachedEntries[key]?.entry {
|
||||
let encoder = Encoder()
|
||||
encoder.encodeRootObject(value)
|
||||
self.valueBox.set(self.table, key: key, value: encoder.readBufferNoCopy())
|
||||
} else {
|
||||
self.valueBox.remove(self.table, key: key)
|
||||
}
|
||||
}
|
||||
|
||||
self.updatedEntryKeys.removeAll()
|
||||
}
|
||||
}
|
||||
}
|
55
Postbox/PreferencesView.swift
Normal file
55
Postbox/PreferencesView.swift
Normal file
@ -0,0 +1,55 @@
|
||||
import Foundation
|
||||
|
||||
final class MutablePreferencesView {
|
||||
fileprivate let keys: Set<ValueBoxKey>
|
||||
fileprivate var values: [ValueBoxKey: PreferencesEntry]
|
||||
|
||||
init(keys: Set<ValueBoxKey>, get: (ValueBoxKey) -> PreferencesEntry?) {
|
||||
self.keys = keys
|
||||
var values: [ValueBoxKey: PreferencesEntry] = [:]
|
||||
for key in keys {
|
||||
if let value = get(key) {
|
||||
values[key] = value
|
||||
}
|
||||
}
|
||||
self.values = values
|
||||
}
|
||||
|
||||
func replay(operations: [PreferencesOperation], get: (ValueBoxKey) -> PreferencesEntry?) -> Bool {
|
||||
var updated = false
|
||||
for operation in operations {
|
||||
switch operation {
|
||||
case let .update(key, value):
|
||||
if self.keys.contains(key) {
|
||||
let currentValue = self.values[key]
|
||||
var updatedValue = false
|
||||
if let value = value, let currentValue = currentValue {
|
||||
if !value.isEqual(to: currentValue) {
|
||||
updatedValue = true
|
||||
}
|
||||
} else if (value != nil) != (currentValue != nil) {
|
||||
updatedValue = true
|
||||
}
|
||||
if updatedValue {
|
||||
if let value = value {
|
||||
self.values[key] = value
|
||||
} else {
|
||||
self.values.removeValue(forKey: key)
|
||||
}
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updated
|
||||
}
|
||||
}
|
||||
|
||||
public final class PreferencesView {
|
||||
public let values: [ValueBoxKey: PreferencesEntry]
|
||||
|
||||
init(_ view: MutablePreferencesView) {
|
||||
self.values = view.values
|
||||
}
|
||||
}
|
@ -69,6 +69,14 @@ private struct SqlitePreparedStatement {
|
||||
return key
|
||||
}
|
||||
|
||||
func int64KeyAt(_ index: Int) -> ValueBoxKey {
|
||||
let value = sqlite3_column_int64(statement, Int32(index))
|
||||
|
||||
let key = ValueBoxKey(length: 9)
|
||||
key.setInt64(0, value: value)
|
||||
return key
|
||||
}
|
||||
|
||||
func destroy() {
|
||||
sqlite3_finalize(statement)
|
||||
}
|
||||
@ -158,15 +166,14 @@ final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
lock.unlock()
|
||||
|
||||
checkpoints.set((Signal<Void, NoError>.single(Void()) |> delay(10.0, queue: Queue.concurrentDefaultQueue()) |> restart).start(next: { [weak self] _ in
|
||||
if let strongSelf = self , strongSelf.database != nil {
|
||||
strongSelf.queue.async {
|
||||
strongSelf.lock.lock()
|
||||
var nLog: Int32 = 0
|
||||
var nFrames: Int32 = 0
|
||||
sqlite3_wal_checkpoint_v2(strongSelf.database.handle, nil, SQLITE_CHECKPOINT_PASSIVE, &nLog, &nFrames)
|
||||
strongSelf.lock.unlock()
|
||||
}
|
||||
checkpoints.set((Signal<Void, NoError>.single(Void()) |> delay(10.0, queue: self.queue) |> restart).start(next: { [weak self] _ in
|
||||
if let strongSelf = self, strongSelf.database != nil {
|
||||
assert(strongSelf.queue.isCurrent())
|
||||
strongSelf.lock.lock()
|
||||
var nLog: Int32 = 0
|
||||
var nFrames: Int32 = 0
|
||||
sqlite3_wal_checkpoint_v2(strongSelf.database.handle, nil, SQLITE_CHECKPOINT_PASSIVE, &nLog, &nFrames)
|
||||
strongSelf.lock.unlock()
|
||||
//print("(SQLite WAL size \(nLog) removed \(nFrames))")
|
||||
}
|
||||
}))
|
||||
@ -706,40 +713,78 @@ final class SqliteValueBox: ValueBox {
|
||||
|
||||
var startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
if start < end {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeValueAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeValueDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
switch table.keyType {
|
||||
case .binary:
|
||||
if start < end {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeValueAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeValueDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.keyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !values(key, value) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
case .int64:
|
||||
if start.reversed < end.reversed {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeValueAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeValueDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeValueDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.int64KeyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !values(key, value) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.keyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !values(key, value) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,39 +795,76 @@ final class SqliteValueBox: ValueBox {
|
||||
|
||||
var startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
if start < end {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeKeyAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeKeyDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
switch table.keyType {
|
||||
case .binary:
|
||||
if start < end {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeKeyAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeKeyDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.keyAt(0)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !keys(key) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
case .int64:
|
||||
if start.reversed < end.reversed {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyAscStatementNoLimit(table, start: start, end: end)
|
||||
} else {
|
||||
statement = self.rangeKeyAscStatementLimit(table, start: start, end: end, limit: limit)
|
||||
}
|
||||
} else {
|
||||
if limit <= 0 {
|
||||
statement = self.rangeKeyDescStatementNoLimit(table, start: end, end: start)
|
||||
} else {
|
||||
statement = self.rangeKeyDescStatementLimit(table, start: end, end: start, limit: limit)
|
||||
}
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.int64KeyAt(0)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !keys(key) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
}
|
||||
|
||||
var currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
startTime = currentTime
|
||||
|
||||
while statement.step() {
|
||||
startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
let key = statement.keyAt(0)
|
||||
|
||||
currentTime = CFAbsoluteTimeGetCurrent()
|
||||
self.readQueryTime += currentTime - startTime
|
||||
|
||||
if !keys(key) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
statement.reset()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,8 @@ protocol ValueBox {
|
||||
func beginStats()
|
||||
func endStats()
|
||||
|
||||
func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, values: @noescape(ValueBoxKey, ReadBuffer) -> Bool, limit: Int)
|
||||
func range(_ table: ValueBoxTable, start: ValueBoxKey, end: ValueBoxKey, keys: @noescape(ValueBoxKey) -> 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 get(_ table: ValueBoxTable, key: ValueBoxKey) -> ReadBuffer?
|
||||
func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool
|
||||
func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer)
|
||||
|
@ -121,6 +121,18 @@ public struct ValueBoxKey: Hashable, CustomStringConvertible, Comparable {
|
||||
}
|
||||
}
|
||||
|
||||
public var reversed: ValueBoxKey {
|
||||
let key = ValueBoxKey(length: self.length)
|
||||
let keyMemory = key.memory.assumingMemoryBound(to: UInt8.self)
|
||||
let selfMemory = self.memory.assumingMemoryBound(to: UInt8.self)
|
||||
var i = self.length - 1
|
||||
while i >= 0 {
|
||||
keyMemory[i] = selfMemory[self.length - 1 - i]
|
||||
i -= 1
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
public var successor: ValueBoxKey {
|
||||
let key = ValueBoxKey(length: self.length)
|
||||
memcpy(key.memory, self.memory, self.length)
|
||||
|
@ -28,6 +28,7 @@ final class ViewTracker {
|
||||
private let getPeerReadState: (PeerId) -> CombinedPeerReadState?
|
||||
private let operationLogGetOperations: (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry]
|
||||
private let operationLogGetTailIndex: (PeerOperationLogTag) -> Int32?
|
||||
private let getPreferencesEntry: (ValueBoxKey) -> PreferencesEntry?
|
||||
|
||||
private var chatListViews = Bag<(MutableChatListView, ValuePipe<(ChatListView, ViewUpdateType)>)>()
|
||||
private var messageHistoryViews: [PeerId: Bag<(MutableMessageHistoryView, ValuePipe<(MessageHistoryView, ViewUpdateType)>)>] = [:]
|
||||
@ -55,8 +56,10 @@ final class ViewTracker {
|
||||
private var timestampBasedMessageAttributesViews = Bag<(MutableTimestampBasedMessageAttributesView, ValuePipe<TimestampBasedMessageAttributesView>)>()
|
||||
|
||||
private var messageViews = Bag<(MutableMessageView, ValuePipe<MessageView>)>()
|
||||
private var preferencesViews = Bag<(MutablePreferencesView, ValuePipe<PreferencesView>)>()
|
||||
private var multiplePeersViews = Bag<(MutableMultiplePeersView, ValuePipe<MultiplePeersView>)>()
|
||||
|
||||
init(queue: Queue, fetchEarlierHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchLaterHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchEarlierChatEntries: @escaping (ChatListIndex?, Int) -> [MutableChatListEntry], fetchLaterChatEntries: @escaping (ChatListIndex?, Int) -> [MutableChatListEntry], fetchAnchorIndex: @escaping (MessageId) -> MessageHistoryAnchorIndex?, renderMessage: @escaping (IntermediateMessage) -> Message, getPeer: @escaping (PeerId) -> Peer?, getPeerNotificationSettings: @escaping (PeerId) -> PeerNotificationSettings?, getCachedPeerData: @escaping (PeerId) -> CachedPeerData?, getPeerPresence: @escaping (PeerId) -> PeerPresence?, getTotalUnreadCount: @escaping () -> Int32, getPeerReadState: @escaping (PeerId) -> CombinedPeerReadState?, operationLogGetOperations: @escaping (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry], operationLogGetTailIndex: @escaping (PeerOperationLogTag) -> Int32?, getTimestampBasedMessageAttributesHead: @escaping (UInt16) -> TimestampBasedMessageAttributesEntry?, unsentMessageIds: [MessageId], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||
init(queue: Queue, fetchEarlierHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchLaterHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchEarlierChatEntries: @escaping (ChatListIndex?, Int) -> [MutableChatListEntry], fetchLaterChatEntries: @escaping (ChatListIndex?, Int) -> [MutableChatListEntry], fetchAnchorIndex: @escaping (MessageId) -> MessageHistoryAnchorIndex?, renderMessage: @escaping (IntermediateMessage) -> Message, getPeer: @escaping (PeerId) -> Peer?, getPeerNotificationSettings: @escaping (PeerId) -> PeerNotificationSettings?, getCachedPeerData: @escaping (PeerId) -> CachedPeerData?, getPeerPresence: @escaping (PeerId) -> PeerPresence?, getTotalUnreadCount: @escaping () -> Int32, getPeerReadState: @escaping (PeerId) -> CombinedPeerReadState?, operationLogGetOperations: @escaping (PeerOperationLogTag, Int32, Int) -> [PeerMergedOperationLogEntry], operationLogGetTailIndex: @escaping (PeerOperationLogTag) -> Int32?, getTimestampBasedMessageAttributesHead: @escaping (UInt16) -> TimestampBasedMessageAttributesEntry?, getPreferencesEntry: @escaping (ValueBoxKey) -> PreferencesEntry?, unsentMessageIds: [MessageId], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||
self.queue = queue
|
||||
self.fetchEarlierHistoryEntries = fetchEarlierHistoryEntries
|
||||
self.fetchLaterHistoryEntries = fetchLaterHistoryEntries
|
||||
@ -73,6 +76,7 @@ final class ViewTracker {
|
||||
self.operationLogGetOperations = operationLogGetOperations
|
||||
self.operationLogGetTailIndex = operationLogGetTailIndex
|
||||
self.getTimestampBasedMessageAttributesHead = getTimestampBasedMessageAttributesHead
|
||||
self.getPreferencesEntry = getPreferencesEntry
|
||||
|
||||
self.unsentMessageView = UnsentMessageHistoryView(ids: unsentMessageIds)
|
||||
self.synchronizeReadStatesView = MutableSynchronizePeerReadStatesView(operations: synchronizePeerReadStateOperations)
|
||||
@ -226,6 +230,28 @@ final class ViewTracker {
|
||||
self.messageViews.remove(index)
|
||||
}
|
||||
|
||||
func addPreferencesView(_ view: MutablePreferencesView) -> (Bag<(MutablePreferencesView, ValuePipe<PreferencesView>)>.Index, Signal<PreferencesView, NoError>) {
|
||||
let record = (view, ValuePipe<PreferencesView>())
|
||||
let index = self.preferencesViews.add(record)
|
||||
|
||||
return (index, record.1.signal())
|
||||
}
|
||||
|
||||
func removePreferencesView(_ index: Bag<(MutablePreferencesView, ValuePipe<PreferencesView>)>.Index) {
|
||||
self.preferencesViews.remove(index)
|
||||
}
|
||||
|
||||
func addMultiplePeersView(_ view: MutableMultiplePeersView) -> (Bag<(MutableMultiplePeersView, ValuePipe<MultiplePeersView>)>.Index, Signal<MultiplePeersView, NoError>) {
|
||||
let record = (view, ValuePipe<MultiplePeersView>())
|
||||
let index = self.multiplePeersViews.add(record)
|
||||
|
||||
return (index, record.1.signal())
|
||||
}
|
||||
|
||||
func removeMultiplePeersView(_ index: Bag<(MutableMultiplePeersView, ValuePipe<MultiplePeersView>)>.Index) {
|
||||
self.multiplePeersViews.remove(index)
|
||||
}
|
||||
|
||||
func refreshViewsDueToExternalTransaction(fetchAroundChatEntries: (_ index: ChatListIndex, _ count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?), fetchAroundHistoryEntries: (_ index: MessageIndex, _ count: Int, _ tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?), fetchUnsentMessageIds: () -> [MessageId], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||
var updateTrackedHolesPeerIds: [PeerId] = []
|
||||
|
||||
@ -263,28 +289,29 @@ final class ViewTracker {
|
||||
|
||||
for (mutableView, pipe) in self.peerViews.copyItems() {
|
||||
var updatedPeers: [PeerId: Peer] = [:]
|
||||
if let peer = self.getPeer(mutableView.peerId) {
|
||||
updatedPeers[mutableView.peerId] = peer
|
||||
}
|
||||
var updatedPeerPresences: [PeerId: PeerPresence] = [:]
|
||||
if let presence = self.getPeerPresence(mutableView.peerId) {
|
||||
updatedPeerPresences[mutableView.peerId] = presence
|
||||
}
|
||||
|
||||
var updatedNotificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||
if let notificationSettings = self.getPeerNotificationSettings(mutableView.peerId) {
|
||||
updatedNotificationSettings[mutableView.peerId] = notificationSettings
|
||||
}
|
||||
|
||||
var updatedCachedPeerData: [PeerId: CachedPeerData] = [:]
|
||||
if let cachedPeerData = self.getCachedPeerData(mutableView.peerId) {
|
||||
updatedCachedPeerData[mutableView.peerId] = cachedPeerData
|
||||
for peerId in cachedPeerData.peerIds {
|
||||
if let peer = self.getPeer(peerId) {
|
||||
updatedPeers[peerId] = peer
|
||||
|
||||
let peerId = mutableView.peerId
|
||||
|
||||
if let peer = self.getPeer(peerId) {
|
||||
updatedPeers[peerId] = peer
|
||||
}
|
||||
if let presence = self.getPeerPresence(peerId) {
|
||||
updatedPeerPresences[peerId] = presence
|
||||
}
|
||||
if let notificationSettings = self.getPeerNotificationSettings(peerId) {
|
||||
updatedNotificationSettings[peerId] = notificationSettings
|
||||
}
|
||||
if let cachedPeerData = self.getCachedPeerData(peerId) {
|
||||
updatedCachedPeerData[peerId] = cachedPeerData
|
||||
for cachedPeerId in cachedPeerData.peerIds {
|
||||
if let peer = self.getPeer(cachedPeerId) {
|
||||
updatedPeers[cachedPeerId] = peer
|
||||
}
|
||||
if let presence = self.getPeerPresence(peerId) {
|
||||
updatedPeerPresences[peerId] = presence
|
||||
if let presence = self.getPeerPresence(cachedPeerId) {
|
||||
updatedPeerPresences[cachedPeerId] = presence
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -360,10 +387,10 @@ final class ViewTracker {
|
||||
if mutableView.replay(transaction.chatListOperations, updatedPeerNotificationSettings: transaction.currentUpdatedPeerNotificationSettings, context: context) {
|
||||
mutableView.complete(context: context, fetchEarlier: self.fetchEarlierChatEntries, fetchLater: self.fetchLaterChatEntries)
|
||||
mutableView.render(self.renderMessage, getPeerNotificationSettings: self.getPeerNotificationSettings)
|
||||
var updateType: ViewUpdateType = .Generic
|
||||
//var updateType: ViewUpdateType = .Generic
|
||||
for operation in transaction.chatListOperations {
|
||||
if case .RemoveHoles = operation {
|
||||
updateType = .UpdateVisible
|
||||
//updateType = .UpdateVisible
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -423,6 +450,18 @@ final class ViewTracker {
|
||||
pipe.putNext(TimestampBasedMessageAttributesView(mutableView))
|
||||
}
|
||||
}
|
||||
|
||||
for (mutableView, pipe) in self.preferencesViews.copyItems() {
|
||||
if mutableView.replay(operations: transaction.currentPreferencesOperations, get: self.getPreferencesEntry) {
|
||||
pipe.putNext(PreferencesView(mutableView))
|
||||
}
|
||||
}
|
||||
|
||||
for (mutableView, pipe) in self.multiplePeersViews.copyItems() {
|
||||
if mutableView.replay(updatedPeers: transaction.currentUpdatedPeers, updatedPeerPresences: transaction.currentUpdatedPeerPresences) {
|
||||
pipe.putNext(MultiplePeersView(mutableView))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateTrackedChatListHoles() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user