mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
295 lines
12 KiB
Swift
295 lines
12 KiB
Swift
import Postbox
|
|
|
|
private enum RichTextTypes: Int32 {
|
|
case empty = 0
|
|
case plain = 1
|
|
case bold = 2
|
|
case italic = 3
|
|
case underline = 4
|
|
case strikethrough = 5
|
|
case fixed = 6
|
|
case url = 7
|
|
case email = 8
|
|
case concat = 9
|
|
case `subscript` = 10
|
|
case superscript = 11
|
|
case marked = 12
|
|
case phone = 13
|
|
case image = 14
|
|
case anchor = 15
|
|
}
|
|
|
|
public indirect enum RichText: PostboxCoding, Equatable {
|
|
case empty
|
|
case plain(String)
|
|
case bold(RichText)
|
|
case italic(RichText)
|
|
case underline(RichText)
|
|
case strikethrough(RichText)
|
|
case fixed(RichText)
|
|
case url(text: RichText, url: String, webpageId: MediaId?)
|
|
case email(text: RichText, email: String)
|
|
case concat([RichText])
|
|
case `subscript`(RichText)
|
|
case superscript(RichText)
|
|
case marked(RichText)
|
|
case phone(text: RichText, phone: String)
|
|
case image(id: MediaId, dimensions: PixelDimensions)
|
|
case anchor(text: RichText, name: String)
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
switch decoder.decodeInt32ForKey("r", orElse: 0) {
|
|
case RichTextTypes.empty.rawValue:
|
|
self = .empty
|
|
case RichTextTypes.plain.rawValue:
|
|
self = .plain(decoder.decodeStringForKey("s", orElse: ""))
|
|
case RichTextTypes.bold.rawValue:
|
|
self = .bold(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.italic.rawValue:
|
|
self = .italic(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.underline.rawValue:
|
|
self = .underline(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.strikethrough.rawValue:
|
|
self = .strikethrough(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.fixed.rawValue:
|
|
self = .fixed(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.url.rawValue:
|
|
let webpageIdNamespace: Int32? = decoder.decodeOptionalInt32ForKey("w.n")
|
|
let webpageIdId: Int64? = decoder.decodeOptionalInt64ForKey("w.i")
|
|
var webpageId: MediaId?
|
|
if let webpageIdNamespace = webpageIdNamespace, let webpageIdId = webpageIdId {
|
|
webpageId = MediaId(namespace: webpageIdNamespace, id: webpageIdId)
|
|
}
|
|
self = .url(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, url: decoder.decodeStringForKey("u", orElse: ""), webpageId: webpageId)
|
|
case RichTextTypes.email.rawValue:
|
|
self = .email(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, email: decoder.decodeStringForKey("e", orElse: ""))
|
|
case RichTextTypes.concat.rawValue:
|
|
self = .concat(decoder.decodeObjectArrayWithDecoderForKey("a"))
|
|
case RichTextTypes.subscript.rawValue:
|
|
self = .subscript(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.superscript.rawValue:
|
|
self = .superscript(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.marked.rawValue:
|
|
self = .marked(decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText)
|
|
case RichTextTypes.phone.rawValue:
|
|
self = .phone(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, phone: decoder.decodeStringForKey("p", orElse: ""))
|
|
case RichTextTypes.image.rawValue:
|
|
self = .image(id: MediaId(namespace: decoder.decodeInt32ForKey("i.n", orElse: 0), id: decoder.decodeInt64ForKey("i.i", orElse: 0)), dimensions: PixelDimensions(width: decoder.decodeInt32ForKey("sw", orElse: 0), height: decoder.decodeInt32ForKey("sh", orElse: 0)))
|
|
case RichTextTypes.anchor.rawValue:
|
|
self = .anchor(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, name: decoder.decodeStringForKey("n", orElse: ""))
|
|
default:
|
|
self = .empty
|
|
}
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
switch self {
|
|
case .empty:
|
|
encoder.encodeInt32(RichTextTypes.empty.rawValue, forKey: "r")
|
|
case let .plain(string):
|
|
encoder.encodeInt32(RichTextTypes.plain.rawValue, forKey: "r")
|
|
encoder.encodeString(string, forKey: "s")
|
|
case let .bold(text):
|
|
encoder.encodeInt32(RichTextTypes.bold.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .italic(text):
|
|
encoder.encodeInt32(RichTextTypes.italic.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .underline(text):
|
|
encoder.encodeInt32(RichTextTypes.underline.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .strikethrough(text):
|
|
encoder.encodeInt32(RichTextTypes.strikethrough.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .fixed(text):
|
|
encoder.encodeInt32(RichTextTypes.fixed.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .url(text, url, webpageId):
|
|
encoder.encodeInt32(RichTextTypes.url.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
encoder.encodeString(url, forKey: "u")
|
|
if let webpageId = webpageId {
|
|
encoder.encodeInt32(webpageId.namespace, forKey: "w.n")
|
|
encoder.encodeInt64(webpageId.id, forKey: "w.i")
|
|
} else {
|
|
encoder.encodeNil(forKey: "w.n")
|
|
encoder.encodeNil(forKey: "w.i")
|
|
}
|
|
case let .email(text, email):
|
|
encoder.encodeInt32(RichTextTypes.email.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
encoder.encodeString(email, forKey: "e")
|
|
case let .concat(texts):
|
|
encoder.encodeInt32(RichTextTypes.concat.rawValue, forKey: "r")
|
|
encoder.encodeObjectArray(texts, forKey: "a")
|
|
case let .subscript(text):
|
|
encoder.encodeInt32(RichTextTypes.subscript.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .superscript(text):
|
|
encoder.encodeInt32(RichTextTypes.superscript.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .marked(text):
|
|
encoder.encodeInt32(RichTextTypes.marked.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
case let .phone(text, phone):
|
|
encoder.encodeInt32(RichTextTypes.phone.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
encoder.encodeString(phone, forKey: "p")
|
|
case let .image(id, dimensions):
|
|
encoder.encodeInt32(RichTextTypes.image.rawValue, forKey: "r")
|
|
encoder.encodeInt32(id.namespace, forKey: "i.n")
|
|
encoder.encodeInt64(id.id, forKey: "i.i")
|
|
encoder.encodeInt32(Int32(dimensions.width), forKey: "sw")
|
|
encoder.encodeInt32(Int32(dimensions.height), forKey: "sh")
|
|
case let .anchor(text, name):
|
|
encoder.encodeInt32(RichTextTypes.anchor.rawValue, forKey: "r")
|
|
encoder.encodeObject(text, forKey: "t")
|
|
encoder.encodeString(name, forKey: "n")
|
|
}
|
|
}
|
|
|
|
public static func ==(lhs: RichText, rhs: RichText) -> Bool {
|
|
switch lhs {
|
|
case .empty:
|
|
if case .empty = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .plain(string):
|
|
if case .plain(string) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .bold(text):
|
|
if case .bold(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .italic(text):
|
|
if case .italic(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .underline(text):
|
|
if case .underline(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .strikethrough(text):
|
|
if case .strikethrough(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .fixed(text):
|
|
if case .fixed(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .url(lhsText, lhsUrl, lhsWebpageId):
|
|
if case let .url(rhsText, rhsUrl, rhsWebpageId) = rhs, lhsText == rhsText && lhsUrl == rhsUrl && lhsWebpageId == rhsWebpageId {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .email(text, email):
|
|
if case .email(text, email) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .concat(lhsTexts):
|
|
if case let .concat(rhsTexts) = rhs, lhsTexts == rhsTexts {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .subscript(text):
|
|
if case .subscript(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .superscript(text):
|
|
if case .superscript(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .marked(text):
|
|
if case .marked(text) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .phone(text, phone):
|
|
if case .phone(text, phone) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .image(id, dimensions):
|
|
if case .image(id, dimensions) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .anchor(text, name):
|
|
if case .anchor(text, name) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension RichText {
|
|
var plainText: String {
|
|
switch self {
|
|
case .empty:
|
|
return ""
|
|
case let .plain(string):
|
|
return string
|
|
case let .bold(text):
|
|
return text.plainText
|
|
case let .italic(text):
|
|
return text.plainText
|
|
case let .underline(text):
|
|
return text.plainText
|
|
case let .strikethrough(text):
|
|
return text.plainText
|
|
case let .fixed(text):
|
|
return text.plainText
|
|
case let .url(text, _, _):
|
|
return text.plainText
|
|
case let .email(text, _):
|
|
return text.plainText
|
|
case let .concat(texts):
|
|
var string = ""
|
|
for text in texts {
|
|
string += text.plainText
|
|
}
|
|
return string
|
|
case let .subscript(text):
|
|
return text.plainText
|
|
case let .superscript(text):
|
|
return text.plainText
|
|
case let .marked(text):
|
|
return text.plainText
|
|
case let .phone(text, _):
|
|
return text.plainText
|
|
case .image:
|
|
return ""
|
|
case let .anchor(text, _):
|
|
return text.plainText
|
|
}
|
|
}
|
|
}
|