mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
279 lines
11 KiB
Swift
279 lines
11 KiB
Swift
import Foundation
|
|
import Postbox
|
|
|
|
public struct TelegramMediaPollOption: Equatable, PostboxCoding {
|
|
public let text: String
|
|
public let opaqueIdentifier: Data
|
|
|
|
public init(text: String, opaqueIdentifier: Data) {
|
|
self.text = text
|
|
self.opaqueIdentifier = opaqueIdentifier
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
self.text = decoder.decodeStringForKey("t", orElse: "")
|
|
self.opaqueIdentifier = decoder.decodeDataForKey("i") ?? Data()
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
encoder.encodeString(self.text, forKey: "t")
|
|
encoder.encodeData(self.opaqueIdentifier, forKey: "i")
|
|
}
|
|
}
|
|
|
|
public struct TelegramMediaPollOptionVoters: Equatable, PostboxCoding {
|
|
public let selected: Bool
|
|
public let opaqueIdentifier: Data
|
|
public let count: Int32
|
|
public let isCorrect: Bool
|
|
|
|
public init(selected: Bool, opaqueIdentifier: Data, count: Int32, isCorrect: Bool) {
|
|
self.selected = selected
|
|
self.opaqueIdentifier = opaqueIdentifier
|
|
self.count = count
|
|
self.isCorrect = isCorrect
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
self.selected = decoder.decodeInt32ForKey("s", orElse: 0) != 0
|
|
self.opaqueIdentifier = decoder.decodeDataForKey("i") ?? Data()
|
|
self.count = decoder.decodeInt32ForKey("c", orElse: 0)
|
|
self.isCorrect = decoder.decodeInt32ForKey("cr", orElse: 0) != 0
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
encoder.encodeInt32(self.selected ? 1 : 0, forKey: "s")
|
|
encoder.encodeData(self.opaqueIdentifier, forKey: "i")
|
|
encoder.encodeInt32(self.count, forKey: "c")
|
|
encoder.encodeInt32(self.isCorrect ? 1 : 0, forKey: "cr")
|
|
}
|
|
}
|
|
|
|
public struct TelegramMediaPollResults: Equatable, PostboxCoding {
|
|
public struct Solution: Equatable {
|
|
public let text: String
|
|
public let entities: [MessageTextEntity]
|
|
|
|
public init(text: String, entities: [MessageTextEntity]) {
|
|
self.text = text
|
|
self.entities = entities
|
|
}
|
|
}
|
|
|
|
public let voters: [TelegramMediaPollOptionVoters]?
|
|
public let totalVoters: Int32?
|
|
public let recentVoters: [PeerId]
|
|
public let solution: TelegramMediaPollResults.Solution?
|
|
|
|
public init(voters: [TelegramMediaPollOptionVoters]?, totalVoters: Int32?, recentVoters: [PeerId], solution: TelegramMediaPollResults.Solution?) {
|
|
self.voters = voters
|
|
self.totalVoters = totalVoters
|
|
self.recentVoters = recentVoters
|
|
self.solution = solution
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
self.voters = decoder.decodeOptionalObjectArrayWithDecoderForKey("v")
|
|
self.totalVoters = decoder.decodeOptionalInt32ForKey("t")
|
|
self.recentVoters = decoder.decodeInt64ArrayForKey("rv").map(PeerId.init)
|
|
if let text = decoder.decodeOptionalStringForKey("sol") {
|
|
let entities: [MessageTextEntity] = decoder.decodeObjectArrayWithDecoderForKey("solent")
|
|
self.solution = TelegramMediaPollResults.Solution(text: text, entities: entities)
|
|
} else {
|
|
self.solution = nil
|
|
}
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
if let voters = self.voters {
|
|
encoder.encodeObjectArray(voters, forKey: "v")
|
|
} else {
|
|
encoder.encodeNil(forKey: "v")
|
|
}
|
|
if let totalVoters = self.totalVoters {
|
|
encoder.encodeInt32(totalVoters, forKey: "t")
|
|
} else {
|
|
encoder.encodeNil(forKey: "t")
|
|
}
|
|
encoder.encodeInt64Array(self.recentVoters.map { $0.toInt64() }, forKey: "rv")
|
|
if let solution = self.solution {
|
|
encoder.encodeString(solution.text, forKey: "sol")
|
|
encoder.encodeObjectArray(solution.entities, forKey: "solent")
|
|
} else {
|
|
encoder.encodeNil(forKey: "sol")
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum TelegramMediaPollPublicity: Int32 {
|
|
case anonymous
|
|
case `public`
|
|
}
|
|
|
|
public enum TelegramMediaPollKind: Equatable, PostboxCoding {
|
|
case poll(multipleAnswers: Bool)
|
|
case quiz
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
switch decoder.decodeInt32ForKey("_v", orElse: 0) {
|
|
case 0:
|
|
self = .poll(multipleAnswers: decoder.decodeInt32ForKey("m", orElse: 0) != 0)
|
|
case 1:
|
|
self = .quiz
|
|
default:
|
|
assertionFailure()
|
|
self = .poll(multipleAnswers: false)
|
|
}
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
switch self {
|
|
case let .poll(multipleAnswers):
|
|
encoder.encodeInt32(0, forKey: "_v")
|
|
encoder.encodeInt32(multipleAnswers ? 1 : 0, forKey: "m")
|
|
case .quiz:
|
|
encoder.encodeInt32(1, forKey: "_v")
|
|
}
|
|
}
|
|
}
|
|
|
|
public final class TelegramMediaPoll: Media, Equatable {
|
|
public var id: MediaId? {
|
|
return self.pollId
|
|
}
|
|
public let pollId: MediaId
|
|
public var peerIds: [PeerId] {
|
|
return results.recentVoters
|
|
}
|
|
|
|
public let publicity: TelegramMediaPollPublicity
|
|
public let kind: TelegramMediaPollKind
|
|
|
|
public let text: String
|
|
public let options: [TelegramMediaPollOption]
|
|
public let correctAnswers: [Data]?
|
|
public let results: TelegramMediaPollResults
|
|
public let isClosed: Bool
|
|
public let deadlineTimeout: Int32?
|
|
|
|
public init(pollId: MediaId, publicity: TelegramMediaPollPublicity, kind: TelegramMediaPollKind, text: String, options: [TelegramMediaPollOption], correctAnswers: [Data]?, results: TelegramMediaPollResults, isClosed: Bool, deadlineTimeout: Int32?) {
|
|
self.pollId = pollId
|
|
self.publicity = publicity
|
|
self.kind = kind
|
|
self.text = text
|
|
self.options = options
|
|
self.correctAnswers = correctAnswers
|
|
self.results = results
|
|
self.isClosed = isClosed
|
|
self.deadlineTimeout = deadlineTimeout
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
if let idBytes = decoder.decodeBytesForKeyNoCopy("i") {
|
|
self.pollId = MediaId(idBytes)
|
|
} else {
|
|
self.pollId = MediaId(namespace: Namespaces.Media.LocalPoll, id: 0)
|
|
}
|
|
self.publicity = TelegramMediaPollPublicity(rawValue: decoder.decodeInt32ForKey("pb", orElse: 0)) ?? TelegramMediaPollPublicity.anonymous
|
|
self.kind = decoder.decodeObjectForKey("kn", decoder: { TelegramMediaPollKind(decoder: $0) }) as? TelegramMediaPollKind ?? TelegramMediaPollKind.poll(multipleAnswers: false)
|
|
self.text = decoder.decodeStringForKey("t", orElse: "")
|
|
self.options = decoder.decodeObjectArrayWithDecoderForKey("os")
|
|
self.correctAnswers = decoder.decodeOptionalDataArrayForKey("ca")
|
|
self.results = decoder.decodeObjectForKey("rs", decoder: { TelegramMediaPollResults(decoder: $0) }) as? TelegramMediaPollResults ?? TelegramMediaPollResults(voters: nil, totalVoters: nil, recentVoters: [], solution: nil)
|
|
self.isClosed = decoder.decodeInt32ForKey("ic", orElse: 0) != 0
|
|
self.deadlineTimeout = decoder.decodeOptionalInt32ForKey("dt")
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
let buffer = WriteBuffer()
|
|
self.pollId.encodeToBuffer(buffer)
|
|
encoder.encodeInt32(self.publicity.rawValue, forKey: "pb")
|
|
encoder.encodeObject(self.kind, forKey: "kn")
|
|
encoder.encodeBytes(buffer, forKey: "i")
|
|
encoder.encodeString(self.text, forKey: "t")
|
|
encoder.encodeObjectArray(self.options, forKey: "os")
|
|
if let correctAnswers = self.correctAnswers {
|
|
encoder.encodeDataArray(correctAnswers, forKey: "ca")
|
|
} else {
|
|
encoder.encodeNil(forKey: "ca")
|
|
}
|
|
encoder.encodeObject(results, forKey: "rs")
|
|
encoder.encodeInt32(self.isClosed ? 1 : 0, forKey: "ic")
|
|
if let deadlineTimeout = self.deadlineTimeout {
|
|
encoder.encodeInt32(deadlineTimeout, forKey: "dt")
|
|
} else {
|
|
encoder.encodeNil(forKey: "dt")
|
|
}
|
|
}
|
|
|
|
public func isEqual(to other: Media) -> Bool {
|
|
guard let other = other as? TelegramMediaPoll else {
|
|
return false
|
|
}
|
|
return self == other
|
|
}
|
|
|
|
public func isSemanticallyEqual(to other: Media) -> Bool {
|
|
return self.isEqual(to: other)
|
|
}
|
|
|
|
public static func ==(lhs: TelegramMediaPoll, rhs: TelegramMediaPoll) -> Bool {
|
|
if lhs.pollId != rhs.pollId {
|
|
return false
|
|
}
|
|
if lhs.publicity != rhs.publicity {
|
|
return false
|
|
}
|
|
if lhs.kind != rhs.kind {
|
|
return false
|
|
}
|
|
if lhs.text != rhs.text {
|
|
return false
|
|
}
|
|
if lhs.options != rhs.options {
|
|
return false
|
|
}
|
|
if lhs.correctAnswers != rhs.correctAnswers {
|
|
return false
|
|
}
|
|
if lhs.results != rhs.results {
|
|
return false
|
|
}
|
|
if lhs.isClosed != rhs.isClosed {
|
|
return false
|
|
}
|
|
if lhs.deadlineTimeout != rhs.deadlineTimeout {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
public func withUpdatedResults(_ results: TelegramMediaPollResults, min: Bool) -> TelegramMediaPoll {
|
|
let updatedResults: TelegramMediaPollResults
|
|
if min {
|
|
if let currentVoters = self.results.voters, let updatedVoters = results.voters {
|
|
var selectedOpaqueIdentifiers = Set<Data>()
|
|
var correctOpaqueIdentifiers = Set<Data>()
|
|
for voters in currentVoters {
|
|
if voters.selected {
|
|
selectedOpaqueIdentifiers.insert(voters.opaqueIdentifier)
|
|
}
|
|
if voters.isCorrect {
|
|
correctOpaqueIdentifiers.insert(voters.opaqueIdentifier)
|
|
}
|
|
}
|
|
updatedResults = TelegramMediaPollResults(voters: updatedVoters.map({ voters in
|
|
return TelegramMediaPollOptionVoters(selected: selectedOpaqueIdentifiers.contains(voters.opaqueIdentifier), opaqueIdentifier: voters.opaqueIdentifier, count: voters.count, isCorrect: correctOpaqueIdentifiers.contains(voters.opaqueIdentifier))
|
|
}), totalVoters: results.totalVoters, recentVoters: results.recentVoters, solution: results.solution ?? self.results.solution)
|
|
} else if let updatedVoters = results.voters {
|
|
updatedResults = TelegramMediaPollResults(voters: updatedVoters, totalVoters: results.totalVoters, recentVoters: results.recentVoters, solution: results.solution ?? self.results.solution)
|
|
} else {
|
|
updatedResults = TelegramMediaPollResults(voters: self.results.voters, totalVoters: results.totalVoters, recentVoters: results.recentVoters, solution: results.solution ?? self.results.solution)
|
|
}
|
|
} else {
|
|
updatedResults = results
|
|
}
|
|
return TelegramMediaPoll(pollId: self.pollId, publicity: self.publicity, kind: self.kind, text: self.text, options: self.options, correctAnswers: self.correctAnswers, results: updatedResults, isClosed: self.isClosed, deadlineTimeout: self.deadlineTimeout)
|
|
}
|
|
}
|