mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
416 lines
14 KiB
Swift
416 lines
14 KiB
Swift
import Foundation
|
|
|
|
public final class PeerViewEntry {
|
|
public let peerId: PeerId
|
|
public let peer: Peer?
|
|
public let message: RenderedMessage
|
|
|
|
public init(peer: Peer, message: RenderedMessage) {
|
|
self.peerId = peer.id
|
|
self.peer = peer
|
|
self.message = message
|
|
}
|
|
|
|
public init(peerId: PeerId, message: RenderedMessage) {
|
|
self.peerId = peerId
|
|
self.peer = nil
|
|
self.message = message
|
|
}
|
|
|
|
private init(peer: Peer?, peerId: PeerId, message: RenderedMessage) {
|
|
self.peer = peer
|
|
self.peerId = peerId
|
|
self.message = message
|
|
}
|
|
}
|
|
|
|
public struct PeerViewEntryIndex: Equatable, Comparable {
|
|
public let peerId: PeerId
|
|
public let messageIndex: MessageIndex
|
|
|
|
public init(_ entry: PeerViewEntry) {
|
|
self.peerId = entry.peerId
|
|
self.messageIndex = MessageIndex(entry.message.message)
|
|
}
|
|
|
|
public init(peerId: PeerId, messageIndex: MessageIndex) {
|
|
self.peerId = peerId
|
|
self.messageIndex = messageIndex
|
|
}
|
|
|
|
public func earlier() -> PeerViewEntryIndex {
|
|
return PeerViewEntryIndex(peerId: self.peerId, messageIndex: MessageIndex(id: MessageId(peerId: self.messageIndex.id.peerId, namespace: self.messageIndex.id.namespace, id: self.messageIndex.id.id - 1), timestamp: self.messageIndex.timestamp))
|
|
}
|
|
|
|
public func later() -> PeerViewEntryIndex {
|
|
return PeerViewEntryIndex(peerId: self.peerId, messageIndex: MessageIndex(id: MessageId(peerId: self.messageIndex.id.peerId, namespace: self.messageIndex.id.namespace, id: self.messageIndex.id.id + 1), timestamp: self.messageIndex.timestamp))
|
|
}
|
|
}
|
|
|
|
public func ==(lhs: PeerViewEntryIndex, rhs: PeerViewEntryIndex) -> Bool {
|
|
return lhs.peerId == rhs.peerId && lhs.messageIndex == rhs.messageIndex
|
|
}
|
|
|
|
public func <(lhs: PeerViewEntryIndex, rhs: PeerViewEntryIndex) -> Bool {
|
|
if lhs.messageIndex != rhs.messageIndex {
|
|
return lhs.messageIndex < rhs.messageIndex
|
|
}
|
|
|
|
return lhs.peerId < rhs.peerId
|
|
}
|
|
|
|
public final class MutablePeerView: CustomStringConvertible {
|
|
public struct RemoveContext {
|
|
var invalidEarlier = false
|
|
var invalidLater = false
|
|
var removedEntries = false
|
|
}
|
|
|
|
let count: Int
|
|
var earlier: PeerViewEntry?
|
|
var later: PeerViewEntry?
|
|
var entries: [PeerViewEntry]
|
|
|
|
public init(count: Int, earlier: PeerViewEntry?, entries: [PeerViewEntry], later: PeerViewEntry?) {
|
|
self.count = count
|
|
self.earlier = earlier
|
|
self.entries = entries
|
|
self.later = later
|
|
}
|
|
|
|
public func removeEntry(context: RemoveContext?, peerId: PeerId) -> RemoveContext {
|
|
var invalidationContext = context ?? RemoveContext()
|
|
|
|
if let earlier = self.earlier {
|
|
if peerId == earlier.peerId {
|
|
invalidationContext.invalidEarlier = true
|
|
}
|
|
}
|
|
|
|
if let later = self.later {
|
|
if peerId == later.peerId {
|
|
invalidationContext.invalidLater = true
|
|
}
|
|
}
|
|
|
|
var i = 0
|
|
while i < self.entries.count {
|
|
if self.entries[i].peerId == peerId {
|
|
self.entries.removeAtIndex(i)
|
|
invalidationContext.removedEntries = true
|
|
break
|
|
}
|
|
i++
|
|
}
|
|
|
|
return invalidationContext
|
|
}
|
|
|
|
public func addEntry(entry: PeerViewEntry) {
|
|
if self.entries.count == 0 {
|
|
self.entries.append(entry)
|
|
} else {
|
|
let first = PeerViewEntryIndex(self.entries[self.entries.count - 1])
|
|
let last = PeerViewEntryIndex(self.entries[0])
|
|
|
|
let index = PeerViewEntryIndex(entry)
|
|
|
|
var next: PeerViewEntryIndex?
|
|
if let later = self.later {
|
|
next = PeerViewEntryIndex(later)
|
|
}
|
|
|
|
if index < last {
|
|
let earlierEntry = self.earlier
|
|
if earlierEntry == nil || PeerViewEntryIndex(earlierEntry!) < index {
|
|
if self.entries.count < self.count {
|
|
self.entries.insert(entry, atIndex: 0)
|
|
} else {
|
|
self.earlier = entry
|
|
}
|
|
}
|
|
} else if index > first {
|
|
if next != nil && index > next! {
|
|
let laterEntry = self.later
|
|
if laterEntry == nil || PeerViewEntryIndex(laterEntry!) > index {
|
|
if self.entries.count < self.count {
|
|
self.entries.append(entry)
|
|
} else {
|
|
self.later = entry
|
|
}
|
|
}
|
|
} else {
|
|
self.entries.append(entry)
|
|
if self.entries.count > self.count {
|
|
let earliest = self.entries[0]
|
|
self.earlier = earliest
|
|
self.entries.removeAtIndex(0)
|
|
}
|
|
}
|
|
} else if index != last && index != first {
|
|
var i = self.entries.count
|
|
while i >= 1 {
|
|
if PeerViewEntryIndex(self.entries[i - 1]) < index {
|
|
break
|
|
}
|
|
i--
|
|
}
|
|
self.entries.insert(entry, atIndex: i)
|
|
if self.entries.count > self.count {
|
|
let earliest = self.entries[0]
|
|
self.earlier = earliest
|
|
self.entries.removeAtIndex(0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public func complete(context: RemoveContext, fetchEarlier: (PeerViewEntryIndex?, Int) -> [PeerViewEntry], fetchLater: (PeerViewEntryIndex?, Int) -> [PeerViewEntry]) {
|
|
if context.removedEntries && self.entries.count != self.count {
|
|
var addedEntries: [PeerViewEntry] = []
|
|
|
|
var latestAnchor: PeerViewEntryIndex?
|
|
|
|
if self.entries.count != 0 {
|
|
latestAnchor = PeerViewEntryIndex(self.entries[self.entries.count - 1])
|
|
} else if let later = self.later {
|
|
latestAnchor = PeerViewEntryIndex(later)
|
|
}
|
|
|
|
if let later = self.later {
|
|
addedEntries += fetchLater(PeerViewEntryIndex(later).earlier(), self.count)
|
|
}
|
|
if let earlier = self.earlier {
|
|
addedEntries += fetchEarlier(PeerViewEntryIndex(earlier).later(), self.count)
|
|
}
|
|
|
|
addedEntries += self.entries
|
|
addedEntries.sortInPlace({ PeerViewEntryIndex($0) < PeerViewEntryIndex($1) })
|
|
|
|
var i = addedEntries.count - 1
|
|
while i >= 1 {
|
|
if PeerViewEntryIndex(addedEntries[i]) == PeerViewEntryIndex(addedEntries[i - 1]) {
|
|
addedEntries.removeAtIndex(i)
|
|
}
|
|
i--
|
|
}
|
|
self.entries = []
|
|
|
|
var anchorIndex = addedEntries.count - 1
|
|
if let latestAnchor = latestAnchor {
|
|
var i = addedEntries.count - 1
|
|
while i >= 0 {
|
|
if PeerViewEntryIndex(addedEntries[i]) <= latestAnchor {
|
|
anchorIndex = i
|
|
break
|
|
}
|
|
i--
|
|
}
|
|
}
|
|
|
|
self.later = nil
|
|
if anchorIndex + 1 < addedEntries.count {
|
|
let i = anchorIndex + 1
|
|
while i < addedEntries.count {
|
|
self.later = addedEntries[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
i = anchorIndex
|
|
while i >= 0 && i > anchorIndex - self.count {
|
|
self.entries.insert(addedEntries[i], atIndex: 0)
|
|
i--
|
|
}
|
|
|
|
self.earlier = nil
|
|
if anchorIndex - self.count >= 0 {
|
|
i = anchorIndex - self.count
|
|
while i >= 0 {
|
|
self.earlier = addedEntries[i]
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
var earlyIndex: PeerViewEntryIndex?
|
|
if self.entries.count != 0 {
|
|
earlyIndex = PeerViewEntryIndex(self.entries[0])
|
|
}
|
|
|
|
let earlierEntries = fetchEarlier(earlyIndex, 1)
|
|
if earlierEntries.count == 0 {
|
|
self.earlier = nil
|
|
} else {
|
|
self.earlier = earlierEntries[0]
|
|
}
|
|
|
|
var lateIndex: PeerViewEntryIndex?
|
|
if self.entries.count != 0 {
|
|
lateIndex = PeerViewEntryIndex(self.entries[self.entries.count - 1])
|
|
}
|
|
|
|
let laterEntries = fetchLater(lateIndex, 1)
|
|
if laterEntries.count == 0 {
|
|
self.later = nil
|
|
} else {
|
|
self.later = laterEntries[0]
|
|
}
|
|
}
|
|
}
|
|
|
|
public func updatePeers(peers: [PeerId : Peer]) -> Bool {
|
|
var updated = false
|
|
|
|
if let earlier = self.earlier {
|
|
if let peer = peers[earlier.peerId] {
|
|
self.earlier = PeerViewEntry(peer: peer, message: earlier.message)
|
|
updated = true
|
|
}
|
|
}
|
|
|
|
if let later = self.later {
|
|
if let peer = peers[later.peerId] {
|
|
self.later = PeerViewEntry(peer: peer, message: later.message)
|
|
updated = true
|
|
}
|
|
}
|
|
|
|
var i = 0
|
|
while i < self.entries.count {
|
|
if let peer = peers[self.entries[i].peerId] {
|
|
self.entries[i] = PeerViewEntry(peer: peer, message: self.entries[i].message)
|
|
updated = true
|
|
}
|
|
i++
|
|
}
|
|
|
|
return updated
|
|
}
|
|
|
|
public func incompleteMessages() -> [Message] {
|
|
var result: [Message] = []
|
|
|
|
if let earlier = self.earlier {
|
|
if earlier.message.incomplete {
|
|
result.append(earlier.message.message)
|
|
}
|
|
}
|
|
if let later = self.later {
|
|
if later.message.incomplete {
|
|
result.append(later.message.message)
|
|
}
|
|
}
|
|
|
|
for entry in self.entries {
|
|
if entry.message.incomplete {
|
|
result.append(entry.message.message)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
public func completeMessages(messages: [MessageId : RenderedMessage]) {
|
|
if let earlier = self.earlier {
|
|
if let message = messages[earlier.message.message.id] {
|
|
self.earlier = PeerViewEntry(peer: earlier.peer, peerId: earlier.peerId, message: message)
|
|
}
|
|
}
|
|
if let later = self.later {
|
|
if let message = messages[later.message.message.id] {
|
|
self.later = PeerViewEntry(peer: later.peer, peerId: later.peerId, message: message)
|
|
}
|
|
}
|
|
|
|
var i = 0
|
|
while i < self.entries.count {
|
|
if let message = messages[self.entries[i].message.message.id] {
|
|
self.entries[i] = PeerViewEntry(peer: self.entries[i].peer, peerId: self.entries[i].peerId, message: message)
|
|
}
|
|
i++
|
|
}
|
|
}
|
|
|
|
public var description: String {
|
|
var string = ""
|
|
|
|
if let earlier = self.earlier {
|
|
string += "more("
|
|
string += "(p \(earlier.peerId.namespace):\(earlier.peerId.id), m \(earlier.message.message.id.namespace):\(earlier.message.message.id.id)—\(earlier.message.message.timestamp)"
|
|
string += ") "
|
|
}
|
|
|
|
string += "["
|
|
var first = true
|
|
for entry in self.entries {
|
|
if first {
|
|
first = false
|
|
} else {
|
|
string += ", "
|
|
}
|
|
string += "(p \(entry.peerId.namespace):\(entry.peerId.id), m \(entry.message.message.id.namespace):\(entry.message.message.id.id)—\(entry.message.message.timestamp))"
|
|
}
|
|
string += "]"
|
|
|
|
if let later = self.later {
|
|
string += " more("
|
|
string += "(p \(later.peerId.namespace):\(later.peerId), m \(later.message.message.id.namespace):\(later.message.message.id.id)—\(later.message.message.timestamp)"
|
|
string += ")"
|
|
}
|
|
|
|
return string
|
|
}
|
|
}
|
|
|
|
public final class PeerView: CustomStringConvertible {
|
|
let earlier: PeerViewEntryIndex?
|
|
let later: PeerViewEntryIndex?
|
|
public let entries: [PeerViewEntry]
|
|
|
|
init(_ mutableView: MutablePeerView) {
|
|
if let earlier = mutableView.earlier {
|
|
self.earlier = PeerViewEntryIndex(earlier)
|
|
} else {
|
|
self.earlier = nil
|
|
}
|
|
|
|
if let later = mutableView.later {
|
|
self.later = PeerViewEntryIndex(later)
|
|
} else {
|
|
self.later = nil
|
|
}
|
|
|
|
self.entries = mutableView.entries
|
|
}
|
|
|
|
public var description: String {
|
|
var string = ""
|
|
|
|
if let earlier = self.earlier {
|
|
string += "more("
|
|
string += "(p \(earlier.peerId.namespace):\(earlier.peerId.id), m \(earlier.messageIndex.id.namespace):\(earlier.messageIndex.id.id)—\(earlier.messageIndex.timestamp)"
|
|
string += ") "
|
|
}
|
|
|
|
string += "["
|
|
var first = true
|
|
for entry in self.entries {
|
|
if first {
|
|
first = false
|
|
} else {
|
|
string += ", "
|
|
}
|
|
string += "(p \(entry.peerId.namespace):\(entry.peerId.id), m \(entry.message.message.id.namespace):\(entry.message.message.id.id)—\(entry.message.message.timestamp))"
|
|
}
|
|
string += "]"
|
|
|
|
if let later = self.later {
|
|
string += " more("
|
|
string += "(p \(later.peerId.namespace):\(later.peerId), m \(later.messageIndex.id.namespace):\(later.messageIndex.id.id)—\(later.messageIndex.timestamp)"
|
|
string += ")"
|
|
}
|
|
|
|
return string
|
|
}
|
|
}
|