2021-09-23 19:57:25 +03:00

488 lines
14 KiB
Swift

import Postbox
public enum EnginePeer: Equatable {
public typealias Id = PeerId
public struct Presence: Equatable {
public enum Status: Comparable {
case present(until: Int32)
case recently
case lastWeek
case lastMonth
case longTimeAgo
public static func <(lhs: Status, rhs: Status) -> Bool {
switch lhs {
case .longTimeAgo:
switch rhs {
case .longTimeAgo:
return false
case .lastMonth, .lastWeek, .recently, .present:
return true
}
case let .present(until):
switch rhs {
case .longTimeAgo:
return false
case let .present(rhsUntil):
return until < rhsUntil
case .lastWeek, .lastMonth, .recently:
return false
}
case .recently:
switch rhs {
case .longTimeAgo, .lastWeek, .lastMonth, .recently:
return false
case .present:
return true
}
case .lastWeek:
switch rhs {
case .longTimeAgo, .lastMonth, .lastWeek:
return false
case .present, .recently:
return true
}
case .lastMonth:
switch rhs {
case .longTimeAgo, .lastMonth:
return false
case .present, .recently, lastWeek:
return true
}
}
}
}
public var status: Status
public var lastActivity: Int32
public init(status: Status, lastActivity: Int32) {
self.status = status
self.lastActivity = lastActivity
}
}
public struct NotificationSettings: Equatable {
public enum MuteState: Equatable {
case `default`
case unmuted
case muted(until: Int32)
}
public enum MessageSound: Equatable {
case none
case `default`
case bundledModern(id: Int32)
case bundledClassic(id: Int32)
}
public enum DisplayPreviews {
case `default`
case show
case hide
}
public var muteState: MuteState
public var messageSound: MessageSound
public var displayPreviews: DisplayPreviews
public init(
muteState: MuteState,
messageSound: MessageSound,
displayPreviews: DisplayPreviews
) {
self.muteState = muteState
self.messageSound = messageSound
self.displayPreviews = displayPreviews
}
}
public enum IndexName: Equatable {
case title(title: String, addressName: String?)
case personName(first: String, last: String, addressName: String?, phoneNumber: String?)
public var isEmpty: Bool {
switch self {
case let .title(title, addressName):
if !title.isEmpty {
return false
}
if let addressName = addressName, !addressName.isEmpty {
return false
}
return true
case let .personName(first, last, addressName, phoneNumber):
if !first.isEmpty {
return false
}
if !last.isEmpty {
return false
}
if let addressName = addressName, !addressName.isEmpty {
return false
}
if let phoneNumber = phoneNumber, !phoneNumber.isEmpty {
return false
}
return true
}
}
}
case user(TelegramUser)
case legacyGroup(TelegramGroup)
case channel(TelegramChannel)
case secretChat(TelegramSecretChat)
public static func ==(lhs: EnginePeer, rhs: EnginePeer) -> Bool {
switch lhs {
case let .user(user):
if case .user(user) = rhs {
return true
} else {
return false
}
case let .legacyGroup(legacyGroup):
if case .legacyGroup(legacyGroup) = rhs {
return true
} else {
return false
}
case let .channel(channel):
if case .channel(channel) = rhs {
return true
} else {
return false
}
case let .secretChat(secretChat):
if case .secretChat(secretChat) = rhs {
return true
} else {
return false
}
}
}
}
public extension EnginePeer.NotificationSettings.MuteState {
init(_ muteState: PeerMuteState) {
switch muteState {
case .default:
self = .default
case .unmuted:
self = .unmuted
case let .muted(until):
self = .muted(until: until)
}
}
func _asMuteState() -> PeerMuteState {
switch self {
case .default:
return .default
case .unmuted:
return .unmuted
case let .muted(until):
return .muted(until: until)
}
}
}
public extension EnginePeer.NotificationSettings.MessageSound {
init(_ messageSound: PeerMessageSound) {
switch messageSound {
case .none:
self = .none
case .default:
self = .default
case let .bundledClassic(id):
self = .bundledClassic(id: id)
case let .bundledModern(id):
self = .bundledModern(id: id)
}
}
func _asMessageSound() -> PeerMessageSound {
switch self {
case .none:
return .none
case .default:
return .default
case let .bundledClassic(id):
return .bundledClassic(id: id)
case let .bundledModern(id):
return .bundledModern(id: id)
}
}
}
public extension EnginePeer.NotificationSettings.DisplayPreviews {
init(_ displayPreviews: PeerNotificationDisplayPreviews) {
switch displayPreviews {
case .default:
self = .default
case .show:
self = .show
case .hide:
self = .hide
}
}
func _asDisplayPreviews() -> PeerNotificationDisplayPreviews {
switch self {
case .default:
return .default
case .show:
return .show
case .hide:
return .hide
}
}
}
public extension EnginePeer.NotificationSettings {
init(_ notificationSettings: TelegramPeerNotificationSettings) {
self.init(
muteState: MuteState(notificationSettings.muteState),
messageSound: MessageSound(notificationSettings.messageSound),
displayPreviews: DisplayPreviews(notificationSettings.displayPreviews)
)
}
func _asNotificationSettings() -> TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(
muteState: self.muteState._asMuteState(),
messageSound: self.messageSound._asMessageSound(),
displayPreviews: self.displayPreviews._asDisplayPreviews()
)
}
}
public extension EnginePeer.Presence {
init(_ presence: PeerPresence) {
if let presence = presence as? TelegramUserPresence {
let mappedStatus: Status
switch presence.status {
case .none:
mappedStatus = .longTimeAgo
case let .present(until):
mappedStatus = .present(until: until)
case .recently:
mappedStatus = .recently
case .lastWeek:
mappedStatus = .lastWeek
case .lastMonth:
mappedStatus = .lastMonth
}
self.init(status: mappedStatus, lastActivity: presence.lastActivity)
} else {
preconditionFailure()
}
}
func _asPresence() -> TelegramUserPresence {
let mappedStatus: UserPresenceStatus
switch self.status {
case .longTimeAgo:
mappedStatus = .none
case let .present(until):
mappedStatus = .present(until: until)
case .recently:
mappedStatus = .recently
case .lastWeek:
mappedStatus = .lastWeek
case .lastMonth:
mappedStatus = .lastMonth
}
return TelegramUserPresence(status: mappedStatus, lastActivity: self.lastActivity)
}
}
public extension EnginePeer.IndexName {
init(_ indexName: PeerIndexNameRepresentation) {
switch indexName {
case let .title(title, addressName):
self = .title(title: title, addressName: addressName)
case let .personName(first, last, addressName, phoneNumber):
self = .personName(first: first, last: last, addressName: addressName, phoneNumber: phoneNumber)
}
}
func _asIndexName() -> PeerIndexNameRepresentation {
switch self {
case let .title(title, addressName):
return .title(title: title, addressName: addressName)
case let .personName(first, last, addressName, phoneNumber):
return .personName(first: first, last: last, addressName: addressName, phoneNumber: phoneNumber)
}
}
func matchesByTokens(_ other: String) -> Bool {
return self._asIndexName().matchesByTokens(other)
}
func stringRepresentation(lastNameFirst: Bool) -> String {
switch self {
case let .title(title, _):
return title
case let .personName(first, last, _, _):
if lastNameFirst {
return last + first
} else {
return first + last
}
}
}
}
public extension EnginePeer {
var id: Id {
return self._asPeer().id
}
var addressName: String? {
return self._asPeer().addressName
}
var indexName: EnginePeer.IndexName {
return EnginePeer.IndexName(self._asPeer().indexName)
}
var debugDisplayTitle: String {
return self._asPeer().debugDisplayTitle
}
func restrictionText(platform: String, contentSettings: ContentSettings) -> String? {
return self._asPeer().restrictionText(platform: platform, contentSettings: contentSettings)
}
var displayLetters: [String] {
return self._asPeer().displayLetters
}
var profileImageRepresentations: [TelegramMediaImageRepresentation] {
return self._asPeer().profileImageRepresentations
}
var smallProfileImage: TelegramMediaImageRepresentation? {
return self._asPeer().smallProfileImage
}
var largeProfileImage: TelegramMediaImageRepresentation? {
return self._asPeer().largeProfileImage
}
var isDeleted: Bool {
return self._asPeer().isDeleted
}
var isScam: Bool {
return self._asPeer().isScam
}
var isFake: Bool {
return self._asPeer().isFake
}
var isVerified: Bool {
return self._asPeer().isVerified
}
var isService: Bool {
if case let .user(peer) = self {
if peer.id.isReplies {
return true
}
return (peer.id.namespace == Namespaces.Peer.CloudUser && (peer.id.id._internalGetInt64Value() == 777000 || peer.id.id._internalGetInt64Value() == 333000))
}
return false
}
}
public extension EnginePeer {
init(_ peer: Peer) {
switch peer {
case let user as TelegramUser:
self = .user(user)
case let group as TelegramGroup:
self = .legacyGroup(group)
case let channel as TelegramChannel:
self = .channel(channel)
case let secretChat as TelegramSecretChat:
self = .secretChat(secretChat)
default:
preconditionFailure("Unknown peer type")
}
}
func _asPeer() -> Peer {
switch self {
case let .user(user):
return user
case let .legacyGroup(legacyGroup):
return legacyGroup
case let .channel(channel):
return channel
case let .secretChat(secretChat):
return secretChat
}
}
}
public final class EngineRenderedPeer: Equatable {
public let peerId: EnginePeer.Id
public let peers: [EnginePeer.Id: EnginePeer]
public init(peerId: EnginePeer.Id, peers: [EnginePeer.Id: EnginePeer]) {
self.peerId = peerId
self.peers = peers
}
public init(peer: EnginePeer) {
self.peerId = peer.id
self.peers = [peer.id: peer]
}
public static func ==(lhs: EngineRenderedPeer, rhs: EngineRenderedPeer) -> Bool {
if lhs.peerId != rhs.peerId {
return false
}
if lhs.peers != rhs.peers {
return false
}
return true
}
public var peer: EnginePeer? {
return self.peers[self.peerId]
}
public var chatMainPeer: EnginePeer? {
if let peer = self.peers[self.peerId] {
if case let .secretChat(secretChat) = peer {
return self.peers[secretChat.regularPeerId]
} else {
return peer
}
} else {
return nil
}
}
}
public extension EngineRenderedPeer {
convenience init(_ renderedPeer: RenderedPeer) {
var mappedPeers: [EnginePeer.Id: EnginePeer] = [:]
for (id, peer) in renderedPeer.peers {
mappedPeers[id] = EnginePeer(peer)
}
self.init(peerId: renderedPeer.peerId, peers: mappedPeers)
}
convenience init(message: EngineMessage) {
self.init(RenderedPeer(message: message._asMessage()))
}
}