mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
298 lines
11 KiB
Swift
298 lines
11 KiB
Swift
import Foundation
|
|
|
|
public struct PeerViewComponents: OptionSet {
|
|
public var rawValue: Int32
|
|
|
|
public init(rawValue: Int32) {
|
|
self.rawValue = rawValue
|
|
}
|
|
|
|
public static let cachedData = PeerViewComponents(rawValue: 1 << 0)
|
|
public static let subPeers = PeerViewComponents(rawValue: 1 << 1)
|
|
public static let messages = PeerViewComponents(rawValue: 1 << 2)
|
|
public static let groupId = PeerViewComponents(rawValue: 1 << 3)
|
|
|
|
public static let all: PeerViewComponents = [.cachedData, .subPeers, .messages, .groupId]
|
|
}
|
|
|
|
final class MutablePeerView: MutablePostboxView {
|
|
let peerId: PeerId
|
|
let contactPeerId: PeerId
|
|
let components: PeerViewComponents
|
|
var notificationSettings: PeerNotificationSettings?
|
|
var cachedData: CachedPeerData?
|
|
var peers: [PeerId: Peer] = [:]
|
|
var peerPresences: [PeerId: PeerPresence] = [:]
|
|
var messages: [MessageId: Message] = [:]
|
|
var media: [MediaId: Media] = [:]
|
|
var peerIsContact: Bool
|
|
var groupId: PeerGroupId?
|
|
|
|
init(postbox: PostboxImpl, peerId: PeerId, components: PeerViewComponents) {
|
|
self.components = components
|
|
|
|
let getPeer: (PeerId) -> Peer? = { peerId in
|
|
return postbox.peerTable.get(peerId)
|
|
}
|
|
|
|
let getPeerPresence: (PeerId) -> PeerPresence? = { peerId in
|
|
return postbox.peerPresenceTable.get(peerId)
|
|
}
|
|
|
|
self.peerId = peerId
|
|
self.groupId = postbox.chatListIndexTable.get(peerId: peerId).inclusion.groupId
|
|
var peerIds = Set<PeerId>()
|
|
var messageIds = Set<MessageId>()
|
|
peerIds.insert(peerId)
|
|
|
|
if let peer = getPeer(peerId), let associatedPeerId = peer.associatedPeerId {
|
|
peerIds.insert(associatedPeerId)
|
|
self.contactPeerId = associatedPeerId
|
|
self.peerIsContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
|
} else {
|
|
self.contactPeerId = peerId
|
|
}
|
|
self.cachedData = postbox.cachedPeerDataTable.get(contactPeerId)
|
|
self.peerIsContact = postbox.contactsTable.isContact(peerId: self.contactPeerId)
|
|
if let cachedData = self.cachedData {
|
|
peerIds.formUnion(cachedData.peerIds)
|
|
messageIds.formUnion(cachedData.messageIds)
|
|
}
|
|
for id in peerIds {
|
|
if let peer = getPeer(id) {
|
|
self.peers[id] = peer
|
|
}
|
|
if let presence = getPeerPresence(id) {
|
|
self.peerPresences[id] = presence
|
|
}
|
|
}
|
|
if let peer = self.peers[peerId], let associatedPeerId = peer.associatedPeerId {
|
|
if let peer = getPeer(associatedPeerId) {
|
|
self.peers[associatedPeerId] = peer
|
|
}
|
|
if let presence = getPeerPresence(associatedPeerId) {
|
|
self.peerPresences[associatedPeerId] = presence
|
|
}
|
|
self.notificationSettings = postbox.peerNotificationSettingsTable.getEffective(associatedPeerId)
|
|
} else {
|
|
self.notificationSettings = postbox.peerNotificationSettingsTable.getEffective(peerId)
|
|
}
|
|
for id in messageIds {
|
|
if let message = postbox.getMessage(id) {
|
|
self.messages[id] = message
|
|
}
|
|
}
|
|
self.media = renderAssociatedMediaForPeers(postbox: postbox, peers: self.peers)
|
|
}
|
|
|
|
func reset(postbox: PostboxImpl) -> Bool {
|
|
return false
|
|
}
|
|
|
|
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
|
|
let updatedPeers = transaction.currentUpdatedPeers
|
|
let updatedNotificationSettings = transaction.currentUpdatedPeerNotificationSettings
|
|
let updatedCachedPeerData = transaction.currentUpdatedCachedPeerData
|
|
let updatedPeerPresences = transaction.currentUpdatedPeerPresences
|
|
let replaceContactPeerIds = transaction.replaceContactPeerIds
|
|
|
|
let getPeer: (PeerId) -> Peer? = { peerId in
|
|
return postbox.peerTable.get(peerId)
|
|
}
|
|
|
|
let getPeerPresence: (PeerId) -> PeerPresence? = { peerId in
|
|
return postbox.peerPresenceTable.get(peerId)
|
|
}
|
|
|
|
var updated = false
|
|
var peersUpdated = false
|
|
var updateMessages = false
|
|
|
|
if let cachedData = updatedCachedPeerData[self.contactPeerId], self.cachedData == nil || !self.cachedData!.isEqual(to: cachedData) {
|
|
if self.cachedData?.messageIds != cachedData.messageIds {
|
|
updateMessages = true
|
|
}
|
|
|
|
self.cachedData = cachedData
|
|
updated = true
|
|
|
|
var peerIds = Set<PeerId>()
|
|
peerIds.insert(self.peerId)
|
|
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
|
peerIds.insert(associatedPeerId)
|
|
}
|
|
peerIds.formUnion(cachedData.peerIds)
|
|
|
|
for id in peerIds {
|
|
if let peer = updatedPeers[id] {
|
|
self.peers[id] = peer
|
|
peersUpdated = true
|
|
} else if let peer = getPeer(id) {
|
|
self.peers[id] = peer
|
|
peersUpdated = true
|
|
}
|
|
|
|
if let presence = updatedPeerPresences[id] {
|
|
self.peerPresences[id] = presence
|
|
} else if let presence = getPeerPresence(id) {
|
|
self.peerPresences[id] = presence
|
|
}
|
|
}
|
|
|
|
var removePeerIds: [PeerId] = []
|
|
for peerId in self.peers.keys {
|
|
if !peerIds.contains(peerId) {
|
|
removePeerIds.append(peerId)
|
|
}
|
|
}
|
|
|
|
for peerId in removePeerIds {
|
|
self.peers.removeValue(forKey: peerId)
|
|
}
|
|
|
|
removePeerIds.removeAll()
|
|
for peerId in self.peerPresences.keys {
|
|
if !peerIds.contains(peerId) {
|
|
removePeerIds.append(peerId)
|
|
}
|
|
}
|
|
|
|
for peerId in removePeerIds {
|
|
self.peerPresences.removeValue(forKey: peerId)
|
|
}
|
|
} else {
|
|
var peerIds = Set<PeerId>()
|
|
peerIds.insert(self.peerId)
|
|
if let peer = getPeer(self.peerId), let associatedPeerId = peer.associatedPeerId {
|
|
peerIds.insert(associatedPeerId)
|
|
}
|
|
if let cachedData = self.cachedData {
|
|
peerIds.formUnion(cachedData.peerIds)
|
|
}
|
|
|
|
for id in peerIds {
|
|
if let peer = updatedPeers[id] {
|
|
self.peers[id] = peer
|
|
updated = true
|
|
peersUpdated = true
|
|
}
|
|
if let presence = updatedPeerPresences[id] {
|
|
self.peerPresences[id] = presence
|
|
updated = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if peersUpdated {
|
|
self.media = renderAssociatedMediaForPeers(postbox: postbox, peers: self.peers)
|
|
}
|
|
|
|
if let cachedData = self.cachedData, !cachedData.messageIds.isEmpty, let operations = transaction.currentOperationsByPeerId[self.peerId] {
|
|
outer: for operation in operations {
|
|
switch operation {
|
|
case let .InsertMessage(message):
|
|
if cachedData.messageIds.contains(message.id) {
|
|
updateMessages = true
|
|
break outer
|
|
}
|
|
case let .Remove(indicesWithTags):
|
|
for (index, _) in indicesWithTags {
|
|
if cachedData.messageIds.contains(index.id) {
|
|
updateMessages = true
|
|
break outer
|
|
}
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if updateMessages {
|
|
var messages: [MessageId: Message] = [:]
|
|
if let cachedData = self.cachedData {
|
|
for id in cachedData.messageIds {
|
|
if let message = postbox.getMessage(id) {
|
|
messages[id] = message
|
|
}
|
|
}
|
|
}
|
|
self.messages = messages
|
|
updated = true
|
|
}
|
|
|
|
if let peer = self.peers[self.peerId] {
|
|
if let associatedPeerId = peer.associatedPeerId {
|
|
if let (_, notificationSettings) = updatedNotificationSettings[associatedPeerId] {
|
|
self.notificationSettings = notificationSettings
|
|
updated = true
|
|
}
|
|
} else {
|
|
if let (_, notificationSettings) = updatedNotificationSettings[peer.id] {
|
|
self.notificationSettings = notificationSettings
|
|
updated = true
|
|
}
|
|
}
|
|
} else if self.notificationSettings != nil {
|
|
self.notificationSettings = nil
|
|
updated = true
|
|
}
|
|
|
|
if let replaceContactPeerIds = replaceContactPeerIds {
|
|
if self.peerIsContact {
|
|
if !replaceContactPeerIds.contains(self.contactPeerId) {
|
|
self.peerIsContact = false
|
|
updated = true
|
|
}
|
|
} else {
|
|
if replaceContactPeerIds.contains(self.contactPeerId) {
|
|
self.peerIsContact = true
|
|
updated = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if transaction.currentUpdatedChatListInclusions[self.peerId] != nil {
|
|
let groupId = postbox.chatListIndexTable.get(peerId: peerId).inclusion.groupId
|
|
if self.groupId != groupId {
|
|
self.groupId = groupId
|
|
updated = true
|
|
}
|
|
}
|
|
|
|
return updated
|
|
}
|
|
|
|
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
|
|
return false
|
|
}
|
|
|
|
func immutableView() -> PostboxView {
|
|
return PeerView(self)
|
|
}
|
|
}
|
|
|
|
public final class PeerView: PostboxView {
|
|
public let peerId: PeerId
|
|
public let cachedData: CachedPeerData?
|
|
public let notificationSettings: PeerNotificationSettings?
|
|
public let peers: [PeerId: Peer]
|
|
public let peerPresences: [PeerId: PeerPresence]
|
|
public let messages: [MessageId: Message]
|
|
public let media: [MediaId: Media]
|
|
public let peerIsContact: Bool
|
|
public let groupId: PeerGroupId?
|
|
|
|
init(_ mutableView: MutablePeerView) {
|
|
self.peerId = mutableView.peerId
|
|
self.cachedData = mutableView.cachedData
|
|
self.notificationSettings = mutableView.notificationSettings
|
|
self.peers = mutableView.peers
|
|
self.peerPresences = mutableView.peerPresences
|
|
self.messages = mutableView.messages
|
|
self.media = mutableView.media
|
|
self.peerIsContact = mutableView.peerIsContact
|
|
self.groupId = mutableView.groupId
|
|
}
|
|
}
|