import Foundation import Postbox public enum CachedPeerAutoremoveTimeout: Equatable, PostboxCoding { public struct Value: Equatable, PostboxCoding { public var myValue: Int32? public var peerValue: Int32? public var isGlobal: Bool public init(myValue: Int32?, peerValue: Int32?, isGlobal: Bool) { self.myValue = myValue self.peerValue = peerValue self.isGlobal = isGlobal } public init(decoder: PostboxDecoder) { self.myValue = decoder.decodeOptionalInt32ForKey("myValue") self.peerValue = decoder.decodeOptionalInt32ForKey("peerValue") self.isGlobal = decoder.decodeInt32ForKey("isGlobal", orElse: 1) != 0 } public func encode(_ encoder: PostboxEncoder) { if let myValue = self.myValue { encoder.encodeInt32(myValue, forKey: "myValue") } else { encoder.encodeNil(forKey: "myValue") } if let peerValue = self.peerValue { encoder.encodeInt32(peerValue, forKey: "peerValue") } else { encoder.encodeNil(forKey: "peerValue") } encoder.encodeInt32(self.isGlobal ? 1 : 0, forKey: "isGlobal") } public var effectiveValue: Int32? { if let myValue = self.myValue, let peerValue = self.peerValue { return min(myValue, peerValue) } else if let myValue = self.myValue { return myValue } else if let peerValue = self.peerValue { return peerValue } else { return nil } } } case unknown case known(Value?) public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("_v", orElse: 0) { case 1: self = .known(decoder.decodeObjectForKey("v", decoder: Value.init(decoder:)) as? Value) default: self = .unknown } } public func encode(_ encoder: PostboxEncoder) { switch self { case .unknown: encoder.encodeInt32(0, forKey: "_v") case let .known(value): encoder.encodeInt32(1, forKey: "_v") if let value = value { encoder.encodeObject(value, forKey: "v") } else { encoder.encodeNil(forKey: "v") } } } } public final class CachedUserData: CachedPeerData { public let about: String? public let botInfo: BotInfo? public let peerStatusSettings: PeerStatusSettings? public let pinnedMessageId: MessageId? public let isBlocked: Bool public let commonGroupCount: Int32 public let voiceCallsAvailable: Bool public let videoCallsAvailable: Bool public let callsPrivate: Bool public let canPinMessages: Bool public let hasScheduledMessages: Bool public let autoremoveTimeout: CachedPeerAutoremoveTimeout public let peerIds = Set() public let messageIds: Set public let associatedHistoryMessageId: MessageId? = nil public init() { self.about = nil self.botInfo = nil self.peerStatusSettings = nil self.pinnedMessageId = nil self.isBlocked = false self.commonGroupCount = 0 self.voiceCallsAvailable = true self.videoCallsAvailable = true self.callsPrivate = false self.canPinMessages = false self.hasScheduledMessages = false self.autoremoveTimeout = .unknown self.messageIds = Set() } public init(about: String?, botInfo: BotInfo?, peerStatusSettings: PeerStatusSettings?, pinnedMessageId: MessageId?, isBlocked: Bool, commonGroupCount: Int32, voiceCallsAvailable: Bool, videoCallsAvailable: Bool, callsPrivate: Bool, canPinMessages: Bool, hasScheduledMessages: Bool, autoremoveTimeout: CachedPeerAutoremoveTimeout) { self.about = about self.botInfo = botInfo self.peerStatusSettings = peerStatusSettings self.pinnedMessageId = pinnedMessageId self.isBlocked = isBlocked self.commonGroupCount = commonGroupCount self.voiceCallsAvailable = voiceCallsAvailable self.videoCallsAvailable = videoCallsAvailable self.callsPrivate = callsPrivate self.canPinMessages = canPinMessages self.hasScheduledMessages = hasScheduledMessages self.autoremoveTimeout = autoremoveTimeout var messageIds = Set() if let pinnedMessageId = self.pinnedMessageId { messageIds.insert(pinnedMessageId) } self.messageIds = messageIds } public init(decoder: PostboxDecoder) { self.about = decoder.decodeOptionalStringForKey("a") self.botInfo = decoder.decodeObjectForKey("bi") as? BotInfo if let legacyValue = decoder.decodeOptionalInt32ForKey("pcs") { self.peerStatusSettings = PeerStatusSettings(flags: PeerStatusSettings.Flags(rawValue: legacyValue), geoDistance: nil) } else if let peerStatusSettings = decoder.decodeObjectForKey("pss", decoder: { PeerStatusSettings(decoder: $0) }) as? PeerStatusSettings { self.peerStatusSettings = peerStatusSettings } else { self.peerStatusSettings = nil } if let pinnedMessagePeerId = decoder.decodeOptionalInt64ForKey("pm.p"), let pinnedMessageNamespace = decoder.decodeOptionalInt32ForKey("pm.n"), let pinnedMessageId = decoder.decodeOptionalInt32ForKey("pm.i") { self.pinnedMessageId = MessageId(peerId: PeerId(pinnedMessagePeerId), namespace: pinnedMessageNamespace, id: pinnedMessageId) } else { self.pinnedMessageId = nil } self.isBlocked = decoder.decodeInt32ForKey("b", orElse: 0) != 0 self.commonGroupCount = decoder.decodeInt32ForKey("cg", orElse: 0) self.voiceCallsAvailable = decoder.decodeInt32ForKey("ca", orElse: 0) != 0 self.videoCallsAvailable = decoder.decodeInt32ForKey("vca", orElse: 0) != 0 self.callsPrivate = decoder.decodeInt32ForKey("cp", orElse: 0) != 0 self.canPinMessages = decoder.decodeInt32ForKey("cpm", orElse: 0) != 0 self.hasScheduledMessages = decoder.decodeBoolForKey("hsm", orElse: false) self.autoremoveTimeout = decoder.decodeObjectForKey("artv", decoder: CachedPeerAutoremoveTimeout.init(decoder:)) as? CachedPeerAutoremoveTimeout ?? .unknown var messageIds = Set() if let pinnedMessageId = self.pinnedMessageId { messageIds.insert(pinnedMessageId) } self.messageIds = messageIds } public func encode(_ encoder: PostboxEncoder) { if let about = self.about { encoder.encodeString(about, forKey: "a") } else { encoder.encodeNil(forKey: "a") } if let botInfo = self.botInfo { encoder.encodeObject(botInfo, forKey: "bi") } else { encoder.encodeNil(forKey: "bi") } if let peerStatusSettings = self.peerStatusSettings { encoder.encodeObject(peerStatusSettings, forKey: "pss") } else { encoder.encodeNil(forKey: "pss") } if let pinnedMessageId = self.pinnedMessageId { encoder.encodeInt64(pinnedMessageId.peerId.toInt64(), forKey: "pm.p") encoder.encodeInt32(pinnedMessageId.namespace, forKey: "pm.n") encoder.encodeInt32(pinnedMessageId.id, forKey: "pm.i") } else { encoder.encodeNil(forKey: "pm.p") encoder.encodeNil(forKey: "pm.n") encoder.encodeNil(forKey: "pm.i") } encoder.encodeInt32(self.isBlocked ? 1 : 0, forKey: "b") encoder.encodeInt32(self.commonGroupCount, forKey: "cg") encoder.encodeInt32(self.voiceCallsAvailable ? 1 : 0, forKey: "ca") encoder.encodeInt32(self.videoCallsAvailable ? 1 : 0, forKey: "vca") encoder.encodeInt32(self.callsPrivate ? 1 : 0, forKey: "cp") encoder.encodeInt32(self.canPinMessages ? 1 : 0, forKey: "cpm") encoder.encodeBool(self.hasScheduledMessages, forKey: "hsm") encoder.encodeObject(self.autoremoveTimeout, forKey: "artv") } public func isEqual(to: CachedPeerData) -> Bool { guard let other = to as? CachedUserData else { return false } if other.pinnedMessageId != self.pinnedMessageId { return false } if other.canPinMessages != self.canPinMessages { return false } return other.about == self.about && other.botInfo == self.botInfo && self.peerStatusSettings == other.peerStatusSettings && self.isBlocked == other.isBlocked && self.commonGroupCount == other.commonGroupCount && self.voiceCallsAvailable == other.voiceCallsAvailable && self.videoCallsAvailable == other.videoCallsAvailable && self.callsPrivate == other.callsPrivate && self.hasScheduledMessages == other.hasScheduledMessages && self.autoremoveTimeout == other.autoremoveTimeout } public func withUpdatedAbout(_ about: String?) -> CachedUserData { return CachedUserData(about: about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedBotInfo(_ botInfo: BotInfo?) -> CachedUserData { return CachedUserData(about: self.about, botInfo: botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedPeerStatusSettings(_ peerStatusSettings: PeerStatusSettings) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedIsBlocked(_ isBlocked: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedCommonGroupCount(_ commonGroupCount: Int32) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedVoiceCallsAvailable(_ voiceCallsAvailable: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedVideoCallsAvailable(_ videoCallsAvailable: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedCallsPrivate(_ callsPrivate: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedCanPinMessages(_ canPinMessages: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedHasScheduledMessages(_ hasScheduledMessages: Bool) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout) } public func withUpdatedAutoremoveTimeout(_ autoremoveTimeout: CachedPeerAutoremoveTimeout) -> CachedUserData { return CachedUserData(about: self.about, botInfo: self.botInfo, peerStatusSettings: self.peerStatusSettings, pinnedMessageId: self.pinnedMessageId, isBlocked: self.isBlocked, commonGroupCount: self.commonGroupCount, voiceCallsAvailable: self.voiceCallsAvailable, videoCallsAvailable: self.videoCallsAvailable, callsPrivate: self.callsPrivate, canPinMessages: self.canPinMessages, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: autoremoveTimeout) } }