mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-17 19:09:56 +00:00
232 lines
9.1 KiB
Swift
232 lines
9.1 KiB
Swift
import Foundation
|
|
#if os(macOS)
|
|
import PostboxMac
|
|
#else
|
|
import Postbox
|
|
#endif
|
|
|
|
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
|
|
}
|
|
|
|
public indirect enum RichText: Coding, 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])
|
|
|
|
public init(decoder: Decoder) {
|
|
switch decoder.decodeInt32ForKey("r") as Int32 {
|
|
case RichTextTypes.empty.rawValue:
|
|
self = .empty
|
|
case RichTextTypes.plain.rawValue:
|
|
self = .plain(decoder.decodeStringForKey("s"))
|
|
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.decodeInt32ForKey("w.n")
|
|
let webpageIdId: Int64? = decoder.decodeInt64ForKey("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"), webpageId: webpageId)
|
|
case RichTextTypes.email.rawValue:
|
|
self = .email(text: decoder.decodeObjectForKey("t", decoder: { RichText(decoder: $0) }) as! RichText, email: decoder.decodeStringForKey("e"))
|
|
case RichTextTypes.concat.rawValue:
|
|
self = .concat(decoder.decodeObjectArrayWithDecoderForKey("a"))
|
|
default:
|
|
self = .empty
|
|
}
|
|
}
|
|
|
|
public func encode(_ encoder: Encoder) {
|
|
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")
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
extension RichText {
|
|
init(apiText: Api.RichText) {
|
|
switch apiText {
|
|
case .textEmpty:
|
|
self = .empty
|
|
case let .textPlain(text):
|
|
self = .plain(text)
|
|
case let .textBold(text):
|
|
self = .bold(RichText(apiText: text))
|
|
case let .textItalic(text):
|
|
self = .italic(RichText(apiText: text))
|
|
case let .textUnderline(text):
|
|
self = .underline(RichText(apiText: text))
|
|
case let .textStrike(text):
|
|
self = .strikethrough(RichText(apiText: text))
|
|
case let .textFixed(text):
|
|
self = .fixed(RichText(apiText: text))
|
|
case let .textUrl(text, url, webpageId):
|
|
self = .url(text: RichText(apiText: text), url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId))
|
|
case let .textEmail(text, email):
|
|
self = .email(text: RichText(apiText: text), email: email)
|
|
case let .textConcat(texts):
|
|
self = .concat(texts.map({ RichText(apiText: $0) }))
|
|
}
|
|
}
|
|
}
|