Swiftgram/submodules/Postbox/Sources/PostboxView.swift
2024-02-23 15:26:33 +04:00

112 lines
4.0 KiB
Swift

import Foundation
public protocol PostboxView: AnyObject {
}
protocol MutablePostboxView: AnyObject {
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool
func immutableView() -> PostboxView
}
final class CombinedMutableView {
let views: [PostboxViewKey: MutablePostboxView]
init(views: [PostboxViewKey: MutablePostboxView]) {
self.views = views
}
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> (updated: Bool, updateTrackedHoles: Bool) {
var anyUpdated = false
var updateTrackedHoles = false
for (_, view) in self.views {
if let mutableView = view as? MutableMessageHistoryView {
var innerUpdated = false
let previousPeerIds = mutableView.peerIds
if mutableView.replay(postbox: postbox, transaction: transaction) {
innerUpdated = true
}
var updateType: ViewUpdateType = .Generic
switch mutableView.peerIds {
case let .single(peerId, threadId):
for key in transaction.currentPeerHoleOperations.keys {
if key.peerId == peerId && key.threadId == threadId {
updateType = .FillHole
break
}
}
case .associated:
var ids = Set<PeerId>()
switch mutableView.peerIds {
case .single, .external:
assertionFailure()
case let .associated(mainPeerId, associatedId):
ids.insert(mainPeerId)
if let associatedId = associatedId {
ids.insert(associatedId.peerId)
}
}
if !ids.isEmpty {
for key in transaction.currentPeerHoleOperations.keys {
if ids.contains(key.peerId) {
updateType = .FillHole
break
}
}
}
case .external:
break
}
mutableView.updatePeerIds(transaction: transaction)
if mutableView.peerIds != previousPeerIds {
updateType = .UpdateVisible
let _ = mutableView.refreshDueToExternalTransaction(postbox: postbox)
innerUpdated = true
}
if innerUpdated {
anyUpdated = true
updateTrackedHoles = true
let _ = updateType
//pipe.putNext((MessageHistoryView(mutableView), updateType))
}
} else if view.replay(postbox: postbox, transaction: transaction) {
anyUpdated = true
}
}
return (anyUpdated, updateTrackedHoles)
}
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
var updated = false
for (_, view) in self.views {
if view.refreshDueToExternalTransaction(postbox: postbox) {
updated = true
}
}
return updated
}
func immutableView() -> CombinedView {
var result: [PostboxViewKey: PostboxView] = [:]
for (key, view) in self.views {
result[key] = view.immutableView()
}
return CombinedView(views: result)
}
}
public final class CombinedView {
public let views: [PostboxViewKey: PostboxView]
init(views: [PostboxViewKey: PostboxView]) {
self.views = views
}
}