Swiftgram/submodules/Postbox/Sources/PeerReadState.swift
2020-04-24 02:50:19 +04:00

155 lines
5.3 KiB
Swift

public enum PeerReadState: Equatable, CustomStringConvertible {
case idBased(maxIncomingReadId: MessageId.Id, maxOutgoingReadId: MessageId.Id, maxKnownId: MessageId.Id, count: Int32, markedUnread: Bool)
case indexBased(maxIncomingReadIndex: MessageIndex, maxOutgoingReadIndex: MessageIndex, count: Int32, markedUnread: Bool)
public var count: Int32 {
switch self {
case let .idBased(_, _, _, count, _):
return count
case let .indexBased(_, _, count, _):
return count
}
}
public var maxKnownId: MessageId.Id? {
switch self {
case let .idBased(_, _, maxKnownId, _, _):
return maxKnownId
case .indexBased:
return nil
}
}
public var isUnread: Bool {
switch self {
case let .idBased(_, _, _, count, markedUnread):
return count > 0 || markedUnread
case let .indexBased(_, _, count, markedUnread):
return count > 0 || markedUnread
}
}
public var markedUnread: Bool {
switch self {
case let .idBased(_, _, _, _, markedUnread):
return markedUnread
case let .indexBased(_, _, _, markedUnread):
return markedUnread
}
}
func withAddedCount(_ value: Int32) -> PeerReadState {
switch self {
case let .idBased(maxIncomingReadId, maxOutgoingReadId, maxKnownId, count, markedUnread):
return .idBased(maxIncomingReadId: maxIncomingReadId, maxOutgoingReadId: maxOutgoingReadId, maxKnownId: maxKnownId, count: count + value, markedUnread: markedUnread)
case let .indexBased(maxIncomingReadIndex, maxOutgoingReadIndex, count, markedUnread):
return .indexBased(maxIncomingReadIndex: maxIncomingReadIndex, maxOutgoingReadIndex: maxOutgoingReadIndex, count: count + value, markedUnread: markedUnread)
}
}
public var description: String {
switch self {
case let .idBased(maxIncomingReadId, maxOutgoingReadId, maxKnownId, count, markedUnread):
return "(PeerReadState maxIncomingReadId: \(maxIncomingReadId), maxOutgoingReadId: \(maxOutgoingReadId) maxKnownId: \(maxKnownId), count: \(count), markedUnread: \(markedUnread)"
case let .indexBased(maxIncomingReadIndex, maxOutgoingReadIndex, count, markedUnread):
return "(PeerReadState maxIncomingReadIndex: \(maxIncomingReadIndex), maxOutgoingReadIndex: \(maxOutgoingReadIndex), count: \(count), markedUnread: \(markedUnread)"
}
}
func isIncomingMessageIndexRead(_ index: MessageIndex) -> Bool {
switch self {
case let .idBased(maxIncomingReadId, _, _, _, _):
return maxIncomingReadId >= index.id.id
case let .indexBased(maxIncomingReadIndex, _, _, _):
return maxIncomingReadIndex >= index
}
}
func isOutgoingMessageIndexRead(_ index: MessageIndex) -> Bool {
switch self {
case let .idBased(_, maxOutgoingReadId, _, _, _):
return maxOutgoingReadId >= index.id.id
case let .indexBased(_, maxOutgoingReadIndex, _, _):
return maxOutgoingReadIndex >= index
}
}
}
public struct CombinedPeerReadState: Equatable {
public let states: [(MessageId.Namespace, PeerReadState)]
public init(states: [(MessageId.Namespace, PeerReadState)]) {
self.states = states
}
public var count: Int32 {
var result: Int32 = 0
for (_, state) in self.states {
result += state.count
}
return result
}
public var markedUnread: Bool {
for (_, state) in self.states {
if state.markedUnread {
return true
}
}
return false
}
public var isUnread: Bool {
for (_, state) in self.states {
if state.isUnread {
return true
}
}
return false
}
public static func ==(lhs: CombinedPeerReadState, rhs: CombinedPeerReadState) -> Bool {
if lhs.states.count != rhs.states.count {
return false
}
for (lhsNamespace, lhsState) in lhs.states {
var rhsFound = false
inner: for (rhsNamespace, rhsState) in rhs.states {
if rhsNamespace == lhsNamespace {
if lhsState != rhsState {
return false
}
rhsFound = true
break inner
}
}
if !rhsFound {
return false
}
}
return true
}
public func isOutgoingMessageIndexRead(_ index: MessageIndex) -> Bool {
for (namespace, readState) in self.states {
if namespace == index.id.namespace {
return readState.isOutgoingMessageIndexRead(index)
}
}
return false
}
public func isIncomingMessageIndexRead(_ index: MessageIndex) -> Bool {
for (namespace, readState) in self.states {
if namespace == index.id.namespace {
return readState.isIncomingMessageIndexRead(index)
}
}
return false
}
}