mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Update API
This commit is contained in:
parent
5ebc55af73
commit
e17c7d9859
11 changed files with 426 additions and 237 deletions
|
|
@ -649,6 +649,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[681706865] = { return Api.MessageEntity.parse_messageEntityCode($0) }
|
||||
dict[-925956616] = { return Api.MessageEntity.parse_messageEntityCustomEmoji($0) }
|
||||
dict[1692693954] = { return Api.MessageEntity.parse_messageEntityEmail($0) }
|
||||
dict[-1874147385] = { return Api.MessageEntity.parse_messageEntityFormattedDate($0) }
|
||||
dict[1868782349] = { return Api.MessageEntity.parse_messageEntityHashtag($0) }
|
||||
dict[-2106619040] = { return Api.MessageEntity.parse_messageEntityItalic($0) }
|
||||
dict[-100378723] = { return Api.MessageEntity.parse_messageEntityMention($0) }
|
||||
|
|
|
|||
|
|
@ -78,6 +78,18 @@ public extension Api {
|
|||
self.length = length
|
||||
}
|
||||
}
|
||||
public class Cons_messageEntityFormattedDate {
|
||||
public var flags: Int32
|
||||
public var offset: Int32
|
||||
public var length: Int32
|
||||
public var date: Int32
|
||||
public init(flags: Int32, offset: Int32, length: Int32, date: Int32) {
|
||||
self.flags = flags
|
||||
self.offset = offset
|
||||
self.length = length
|
||||
self.date = date
|
||||
}
|
||||
}
|
||||
public class Cons_messageEntityHashtag {
|
||||
public var offset: Int32
|
||||
public var length: Int32
|
||||
|
|
@ -189,6 +201,7 @@ public extension Api {
|
|||
case messageEntityCode(Cons_messageEntityCode)
|
||||
case messageEntityCustomEmoji(Cons_messageEntityCustomEmoji)
|
||||
case messageEntityEmail(Cons_messageEntityEmail)
|
||||
case messageEntityFormattedDate(Cons_messageEntityFormattedDate)
|
||||
case messageEntityHashtag(Cons_messageEntityHashtag)
|
||||
case messageEntityItalic(Cons_messageEntityItalic)
|
||||
case messageEntityMention(Cons_messageEntityMention)
|
||||
|
|
@ -270,6 +283,15 @@ public extension Api {
|
|||
serializeInt32(_data.offset, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.length, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageEntityFormattedDate(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1874147385)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.offset, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.length, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.date, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageEntityHashtag(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1868782349)
|
||||
|
|
@ -380,6 +402,8 @@ public extension Api {
|
|||
return ("messageEntityCustomEmoji", [("offset", _data.offset as Any), ("length", _data.length as Any), ("documentId", _data.documentId as Any)])
|
||||
case .messageEntityEmail(let _data):
|
||||
return ("messageEntityEmail", [("offset", _data.offset as Any), ("length", _data.length as Any)])
|
||||
case .messageEntityFormattedDate(let _data):
|
||||
return ("messageEntityFormattedDate", [("flags", _data.flags as Any), ("offset", _data.offset as Any), ("length", _data.length as Any), ("date", _data.date as Any)])
|
||||
case .messageEntityHashtag(let _data):
|
||||
return ("messageEntityHashtag", [("offset", _data.offset as Any), ("length", _data.length as Any)])
|
||||
case .messageEntityItalic(let _data):
|
||||
|
|
@ -544,6 +568,26 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageEntityFormattedDate(_ reader: BufferReader) -> MessageEntity? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.MessageEntity.messageEntityFormattedDate(Cons_messageEntityFormattedDate(flags: _1!, offset: _2!, length: _3!, date: _4!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageEntityHashtag(_ reader: BufferReader) -> MessageEntity? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
|
|||
case let .messageMediaDocument(messageMediaDocumentData):
|
||||
let (flags, document, altDocuments, coverPhoto, videoTimestamp, ttlSeconds) = (messageMediaDocumentData.flags, messageMediaDocumentData.document, messageMediaDocumentData.altDocuments, messageMediaDocumentData.videoCover, messageMediaDocumentData.videoTimestamp, messageMediaDocumentData.ttlSeconds)
|
||||
if let document = document {
|
||||
if let mediaFile = telegramMediaFileFromApiDocument(document, altDocuments: altDocuments, videoCover: coverPhoto) {
|
||||
if let mediaFile = telegramMediaFileFromApiDocument(document, altDocuments: altDocuments, videoCover: coverPhoto, isLivePhoto: (flags & (1 << 11)) != 0) {
|
||||
return (mediaFile, ttlSeconds, (flags & (1 << 3)) != 0, (flags & (1 << 4)) != 0, nil, videoTimestamp)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -785,6 +785,31 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
|
|||
case let .messageEntityCustomEmoji(messageEntityCustomEmojiData):
|
||||
let (offset, length, documentId) = (messageEntityCustomEmojiData.offset, messageEntityCustomEmojiData.length, messageEntityCustomEmojiData.documentId)
|
||||
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .CustomEmoji(stickerPack: nil, fileId: documentId)))
|
||||
case let .messageEntityFormattedDate(messageEntityFormattedDateData):
|
||||
let (flags, offset, length, date) = (messageEntityFormattedDateData.flags, messageEntityFormattedDateData.offset, messageEntityFormattedDateData.length, messageEntityFormattedDateData.date)
|
||||
let format: MessageTextEntityType.DateTimeFormat
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
format = .relative
|
||||
} else {
|
||||
let timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
timeFormat = .short
|
||||
} else if (flags & (1 << 2)) != 0 {
|
||||
timeFormat = .long
|
||||
} else {
|
||||
timeFormat = .short
|
||||
}
|
||||
let dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
dateFormat = .short
|
||||
} else if (flags & (1 << 4)) != 0 {
|
||||
dateFormat = .long
|
||||
} else {
|
||||
dateFormat = .short
|
||||
}
|
||||
format = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .FormattedDate(format: format, date: date)))
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ extension StickerMaskCoords {
|
|||
}
|
||||
}
|
||||
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute]) -> [TelegramMediaFileAttribute] {
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute], isLivePhoto: Bool = false) -> [TelegramMediaFileAttribute] {
|
||||
var result: [TelegramMediaFileAttribute] = []
|
||||
for attribute in attributes {
|
||||
switch attribute {
|
||||
|
|
@ -137,6 +137,9 @@ func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAtt
|
|||
if (flags & (1 << 3)) != 0 {
|
||||
videoFlags.insert(.isSilent)
|
||||
}
|
||||
if isLivePhoto {
|
||||
videoFlags.insert(.isLivePhoto)
|
||||
}
|
||||
result.append(.Video(duration: Double(duration), size: PixelDimensions(width: w, height: h), flags: videoFlags, preloadSize: preloadSize, coverTime: videoStart, videoCodec: videoCodec))
|
||||
case let .documentAttributeAudio(documentAttributeAudioData):
|
||||
let (flags, duration, title, performer, waveform) = (documentAttributeAudioData.flags, documentAttributeAudioData.duration, documentAttributeAudioData.title, documentAttributeAudioData.performer, documentAttributeAudioData.waveform)
|
||||
|
|
@ -192,11 +195,11 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
|
|||
return (immediateThumbnailData, representations)
|
||||
}
|
||||
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil) -> TelegramMediaFile? {
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil, isLivePhoto: Bool = false) -> TelegramMediaFile? {
|
||||
switch document {
|
||||
case let .document(documentData):
|
||||
let (id, accessHash, fileReference, mimeType, size, thumbs, videoThumbs, dcId, attributes) = (documentData.id, documentData.accessHash, documentData.fileReference, documentData.mimeType, documentData.size, documentData.thumbs, documentData.videoThumbs, documentData.dcId, documentData.attributes)
|
||||
var parsedAttributes = telegramMediaFileAttributesFromApiAttributes(attributes)
|
||||
var parsedAttributes = telegramMediaFileAttributesFromApiAttributes(attributes, isLivePhoto: isLivePhoto)
|
||||
var isSticker = false
|
||||
var isAnimated = false
|
||||
for attribute in parsedAttributes {
|
||||
|
|
@ -238,7 +241,7 @@ func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [A
|
|||
alternativeRepresentations = altDocuments.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
}
|
||||
|
||||
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: size, fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, videoCover: videoCover.flatMap(telegramMediaImageFromApiPhoto), immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes, alternativeRepresentations: alternativeRepresentations)
|
||||
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: size, fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, videoCover: videoCover.flatMap(telegramMediaImageFromApiPhoto), immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes, alternativeRepresentations: alternativeRepresentations)
|
||||
case .documentEmpty:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,52 +10,72 @@ func apiEntitiesFromMessageTextEntities(_ entities: [MessageTextEntity], associa
|
|||
let offset: Int32 = Int32(entity.range.lowerBound)
|
||||
let length: Int32 = Int32(entity.range.upperBound - entity.range.lowerBound)
|
||||
switch entity.type {
|
||||
case .Unknown:
|
||||
break
|
||||
case .Mention:
|
||||
apiEntities.append(.messageEntityMention(.init(offset: offset, length: length)))
|
||||
case .Hashtag:
|
||||
apiEntities.append(.messageEntityHashtag(.init(offset: offset, length: length)))
|
||||
case .BotCommand:
|
||||
apiEntities.append(.messageEntityBotCommand(.init(offset: offset, length: length)))
|
||||
case .Url:
|
||||
apiEntities.append(.messageEntityUrl(.init(offset: offset, length: length)))
|
||||
case .Email:
|
||||
apiEntities.append(.messageEntityEmail(.init(offset: offset, length: length)))
|
||||
case .Bold:
|
||||
apiEntities.append(.messageEntityBold(.init(offset: offset, length: length)))
|
||||
case .Italic:
|
||||
apiEntities.append(.messageEntityItalic(.init(offset: offset, length: length)))
|
||||
case .Code:
|
||||
apiEntities.append(.messageEntityCode(.init(offset: offset, length: length)))
|
||||
case let .Pre(language):
|
||||
apiEntities.append(.messageEntityPre(.init(offset: offset, length: length, language: language ?? "")))
|
||||
case let .TextUrl(url):
|
||||
apiEntities.append(.messageEntityTextUrl(.init(offset: offset, length: length, url: url)))
|
||||
case let .TextMention(peerId):
|
||||
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
|
||||
apiEntities.append(.inputMessageEntityMentionName(.init(offset: offset, length: length, userId: inputUser)))
|
||||
case .Unknown:
|
||||
break
|
||||
case .Mention:
|
||||
apiEntities.append(.messageEntityMention(.init(offset: offset, length: length)))
|
||||
case .Hashtag:
|
||||
apiEntities.append(.messageEntityHashtag(.init(offset: offset, length: length)))
|
||||
case .BotCommand:
|
||||
apiEntities.append(.messageEntityBotCommand(.init(offset: offset, length: length)))
|
||||
case .Url:
|
||||
apiEntities.append(.messageEntityUrl(.init(offset: offset, length: length)))
|
||||
case .Email:
|
||||
apiEntities.append(.messageEntityEmail(.init(offset: offset, length: length)))
|
||||
case .Bold:
|
||||
apiEntities.append(.messageEntityBold(.init(offset: offset, length: length)))
|
||||
case .Italic:
|
||||
apiEntities.append(.messageEntityItalic(.init(offset: offset, length: length)))
|
||||
case .Code:
|
||||
apiEntities.append(.messageEntityCode(.init(offset: offset, length: length)))
|
||||
case let .Pre(language):
|
||||
apiEntities.append(.messageEntityPre(.init(offset: offset, length: length, language: language ?? "")))
|
||||
case let .TextUrl(url):
|
||||
apiEntities.append(.messageEntityTextUrl(.init(offset: offset, length: length, url: url)))
|
||||
case let .TextMention(peerId):
|
||||
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
|
||||
apiEntities.append(.inputMessageEntityMentionName(.init(offset: offset, length: length, userId: inputUser)))
|
||||
}
|
||||
case .PhoneNumber:
|
||||
break
|
||||
case .Strikethrough:
|
||||
apiEntities.append(.messageEntityStrike(.init(offset: offset, length: length)))
|
||||
case let .BlockQuote(isCollapsed):
|
||||
var flags: Int32 = 0
|
||||
if isCollapsed {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
apiEntities.append(.messageEntityBlockquote(.init(flags: flags, offset: offset, length: length)))
|
||||
case .Underline:
|
||||
apiEntities.append(.messageEntityUnderline(.init(offset: offset, length: length)))
|
||||
case .BankCard:
|
||||
apiEntities.append(.messageEntityBankCard(.init(offset: offset, length: length)))
|
||||
case .Spoiler:
|
||||
apiEntities.append(.messageEntitySpoiler(.init(offset: offset, length: length)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
apiEntities.append(.messageEntityCustomEmoji(.init(offset: offset, length: length, documentId: fileId)))
|
||||
case let .FormattedDate(format, date):
|
||||
var flags: Int32 = 0
|
||||
switch format {
|
||||
case .relative:
|
||||
flags |= 1 << 0
|
||||
case let .full(timeFormat, dateFormat):
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
flags |= 1 << 1
|
||||
case .long:
|
||||
flags |= 1 << 2
|
||||
}
|
||||
case .PhoneNumber:
|
||||
break
|
||||
case .Strikethrough:
|
||||
apiEntities.append(.messageEntityStrike(.init(offset: offset, length: length)))
|
||||
case let .BlockQuote(isCollapsed):
|
||||
var flags: Int32 = 0
|
||||
if isCollapsed {
|
||||
flags |= 1 << 0
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
flags |= 1 << 3
|
||||
case .long:
|
||||
flags |= 1 << 4
|
||||
}
|
||||
apiEntities.append(.messageEntityBlockquote(.init(flags: flags, offset: offset, length: length)))
|
||||
case .Underline:
|
||||
apiEntities.append(.messageEntityUnderline(.init(offset: offset, length: length)))
|
||||
case .BankCard:
|
||||
apiEntities.append(.messageEntityBankCard(.init(offset: offset, length: length)))
|
||||
case .Spoiler:
|
||||
apiEntities.append(.messageEntitySpoiler(.init(offset: offset, length: length)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
apiEntities.append(.messageEntityCustomEmoji(.init(offset: offset, length: length, documentId: fileId)))
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
apiEntities.append(.messageEntityFormattedDate(.init(flags: flags, offset: offset, length: length, date: date)))
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||
if let _ = videoCoverPhoto {
|
||||
flags |= 1 << 6
|
||||
}
|
||||
|
||||
|
||||
var ttlSeconds: Int32?
|
||||
var videoTimestamp: Int32?
|
||||
for attribute in attributes {
|
||||
|
|
@ -1213,6 +1213,10 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||
flags |= 1 << 7
|
||||
}
|
||||
|
||||
if file.isLivePhoto {
|
||||
flags |= 1 << 8
|
||||
}
|
||||
|
||||
if ttlSeconds != nil {
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedDocument(.init(flags: flags, file: inputFile, thumb: thumbnailFile, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), stickers: stickers, videoCover: videoCoverPhoto, videoTimestamp: videoTimestamp, ttlSeconds: ttlSeconds)), text), reuploadInfo: nil, cacheReferenceKey: referenceKey)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -822,6 +822,8 @@ private func decryptedEntities73(_ entities: [MessageTextEntity]?) -> [SecretApi
|
|||
break
|
||||
case .CustomEmoji:
|
||||
break
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
@ -875,6 +877,8 @@ private func decryptedEntities101(_ entities: [MessageTextEntity]?) -> [SecretAp
|
|||
break
|
||||
case .CustomEmoji:
|
||||
break
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
@ -928,6 +932,8 @@ private func decryptedEntities144(_ entities: [MessageTextEntity]?) -> [SecretAp
|
|||
result.append(.messageEntitySpoiler(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
result.append(.messageEntityCustomEmoji(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count), documentId: fileId))
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 222
|
||||
return 225
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ public struct TelegramMediaVideoFlags: OptionSet {
|
|||
public static let instantRoundVideo = TelegramMediaVideoFlags(rawValue: 1 << 0)
|
||||
public static let supportsStreaming = TelegramMediaVideoFlags(rawValue: 1 << 1)
|
||||
public static let isSilent = TelegramMediaVideoFlags(rawValue: 1 << 3)
|
||||
public static let isLivePhoto = TelegramMediaVideoFlags(rawValue: 1 << 4)
|
||||
}
|
||||
|
||||
public struct StickerMaskCoords: PostboxCoding, Equatable {
|
||||
|
|
@ -1060,6 +1061,15 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
|||
return false
|
||||
}
|
||||
|
||||
public var isLivePhoto: Bool {
|
||||
for attribute in self.attributes {
|
||||
if case .Video(_, _, let flags, _, _, _) = attribute {
|
||||
return flags.contains(.isLivePhoto)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public var preloadSize: Int32? {
|
||||
for attribute in self.attributes {
|
||||
if case .Video(_, _, _, let preloadSize, _, _) = attribute {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,67 @@ import Postbox
|
|||
public enum MessageTextEntityType: Equatable {
|
||||
public typealias CustomEntityType = Int32
|
||||
|
||||
public enum DateTimeFormat: Equatable {
|
||||
public enum TimeFormat: Equatable {
|
||||
case short
|
||||
case long
|
||||
}
|
||||
|
||||
public enum DateFormat: Equatable {
|
||||
case short
|
||||
case long
|
||||
}
|
||||
|
||||
case relative
|
||||
case full(timeFormat: TimeFormat, dateFormat: DateFormat)
|
||||
|
||||
public init(rawValue: Int32) {
|
||||
if (rawValue & (1 << 0)) != 0 {
|
||||
self = .relative
|
||||
} else {
|
||||
let timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat
|
||||
if (rawValue & (1 << 1)) != 0 {
|
||||
timeFormat = .short
|
||||
} else if (rawValue & (1 << 2)) != 0 {
|
||||
timeFormat = .long
|
||||
} else {
|
||||
timeFormat = .short
|
||||
}
|
||||
let dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat
|
||||
if (rawValue & (1 << 3)) != 0 {
|
||||
dateFormat = .short
|
||||
} else if (rawValue & (1 << 4)) != 0 {
|
||||
dateFormat = .long
|
||||
} else {
|
||||
dateFormat = .short
|
||||
}
|
||||
self = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
}
|
||||
|
||||
public var rawValue: Int32 {
|
||||
var rawValue: Int32 = 0
|
||||
switch self {
|
||||
case .relative:
|
||||
rawValue |= 1 << 0
|
||||
case let .full(timeFormat, dateFormat):
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
rawValue |= 1 << 1
|
||||
case .long:
|
||||
rawValue |= 1 << 2
|
||||
}
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
rawValue |= 1 << 3
|
||||
case .long:
|
||||
rawValue |= 1 << 4
|
||||
}
|
||||
}
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
|
||||
case Unknown
|
||||
case Mention
|
||||
case Hashtag
|
||||
|
|
@ -23,6 +84,7 @@ public enum MessageTextEntityType: Equatable {
|
|||
case BankCard
|
||||
case Spoiler
|
||||
case CustomEmoji(stickerPack: StickerPackReference?, fileId: Int64)
|
||||
case FormattedDate(format: DateTimeFormat, date: Int32)
|
||||
case Custom(type: CustomEntityType)
|
||||
}
|
||||
|
||||
|
|
@ -39,47 +101,49 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
self.range = Int(decoder.decodeInt32ForKey("start", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("end", orElse: 0))
|
||||
let type: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
switch type {
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: decoder.decodeOptionalStringForKey("language"))
|
||||
case 10:
|
||||
self.type = .TextUrl(url: decoder.decodeStringForKey("url", orElse: ""))
|
||||
case 11:
|
||||
self.type = .TextMention(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: decoder.decodeBoolForKey("cl", orElse: false))
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
let stickerPack = decoder.decodeObjectForKey("s", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference
|
||||
self.type = .CustomEmoji(stickerPack: stickerPack, fileId: decoder.decodeInt64ForKey("f", orElse: 0))
|
||||
case Int32.max:
|
||||
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
|
||||
default:
|
||||
self.type = .Unknown
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: decoder.decodeOptionalStringForKey("language"))
|
||||
case 10:
|
||||
self.type = .TextUrl(url: decoder.decodeStringForKey("url", orElse: ""))
|
||||
case 11:
|
||||
self.type = .TextMention(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: decoder.decodeBoolForKey("cl", orElse: false))
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
let stickerPack = decoder.decodeObjectForKey("s", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference
|
||||
self.type = .CustomEmoji(stickerPack: stickerPack, fileId: decoder.decodeInt64ForKey("f", orElse: 0))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: decoder.decodeInt32ForKey("format", orElse: 0)), date: decoder.decodeInt32ForKey("date", orElse: 0))
|
||||
case Int32.max:
|
||||
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
|
||||
default:
|
||||
self.type = .Unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,49 +159,51 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
self.range = Int(rangeStart) ..< Int(rangeEnd)
|
||||
|
||||
switch type {
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: try? container.decodeIfPresent(String.self, forKey: "language"))
|
||||
case 10:
|
||||
let url = (try? container.decode(String.self, forKey: "url")) ?? ""
|
||||
self.type = .TextUrl(url: url)
|
||||
case 11:
|
||||
let peerId = (try? container.decode(Int64.self, forKey: "peerId")) ?? 0
|
||||
self.type = .TextMention(peerId: PeerId(peerId))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: try container.decodeIfPresent(Bool.self, forKey: "cl") ?? false)
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
self.type = .CustomEmoji(stickerPack: try container.decodeIfPresent(StickerPackReference.self, forKey: "s"), fileId: try container.decode(Int64.self, forKey: "f"))
|
||||
case Int32.max:
|
||||
let customType: Int32 = (try? container.decode(Int32.self, forKey: "type")) ?? 0
|
||||
self.type = .Custom(type: customType)
|
||||
default:
|
||||
self.type = .Unknown
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: try? container.decodeIfPresent(String.self, forKey: "language"))
|
||||
case 10:
|
||||
let url = (try? container.decode(String.self, forKey: "url")) ?? ""
|
||||
self.type = .TextUrl(url: url)
|
||||
case 11:
|
||||
let peerId = (try? container.decode(Int64.self, forKey: "peerId")) ?? 0
|
||||
self.type = .TextMention(peerId: PeerId(peerId))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: try container.decodeIfPresent(Bool.self, forKey: "cl") ?? false)
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
self.type = .CustomEmoji(stickerPack: try container.decodeIfPresent(StickerPackReference.self, forKey: "s"), fileId: try container.decode(Int64.self, forKey: "f"))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: try container.decode(Int32.self, forKey: "format")), date: try container.decode(Int32.self, forKey: "date"))
|
||||
case Int32.max:
|
||||
let customType: Int32 = (try? container.decode(Int32.self, forKey: "type")) ?? 0
|
||||
self.type = .Custom(type: customType)
|
||||
default:
|
||||
self.type = .Unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,61 +211,65 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
encoder.encodeInt32(Int32(self.range.lowerBound), forKey: "start")
|
||||
encoder.encodeInt32(Int32(self.range.upperBound), forKey: "end")
|
||||
switch self.type {
|
||||
case .Unknown:
|
||||
encoder.encodeInt32(0, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
encoder.encodeInt32(1, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
encoder.encodeInt32(2, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
encoder.encodeInt32(3, forKey: "_rawValue")
|
||||
case .Url:
|
||||
encoder.encodeInt32(4, forKey: "_rawValue")
|
||||
case .Email:
|
||||
encoder.encodeInt32(5, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
encoder.encodeInt32(6, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
encoder.encodeInt32(7, forKey: "_rawValue")
|
||||
case .Code:
|
||||
encoder.encodeInt32(8, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
encoder.encodeInt32(9, forKey: "_rawValue")
|
||||
if let language = language {
|
||||
encoder.encodeString(language, forKey: "language")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "language")
|
||||
}
|
||||
case let .TextUrl(url):
|
||||
encoder.encodeInt32(10, forKey: "_rawValue")
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
encoder.encodeInt32(11, forKey: "_rawValue")
|
||||
encoder.encodeInt64(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
encoder.encodeInt32(12, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
encoder.encodeInt32(13, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
encoder.encodeInt32(14, forKey: "_rawValue")
|
||||
encoder.encodeBool(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
encoder.encodeInt32(15, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
encoder.encodeInt32(16, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
encoder.encodeInt32(17, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
encoder.encodeInt32(18, forKey: "_rawValue")
|
||||
if let stickerPack = stickerPack {
|
||||
encoder.encodeObject(stickerPack, forKey: "s")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "s")
|
||||
}
|
||||
encoder.encodeInt64(fileId, forKey: "f")
|
||||
case let .Custom(type):
|
||||
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
|
||||
encoder.encodeInt32(type, forKey: "type")
|
||||
case .Unknown:
|
||||
encoder.encodeInt32(0, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
encoder.encodeInt32(1, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
encoder.encodeInt32(2, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
encoder.encodeInt32(3, forKey: "_rawValue")
|
||||
case .Url:
|
||||
encoder.encodeInt32(4, forKey: "_rawValue")
|
||||
case .Email:
|
||||
encoder.encodeInt32(5, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
encoder.encodeInt32(6, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
encoder.encodeInt32(7, forKey: "_rawValue")
|
||||
case .Code:
|
||||
encoder.encodeInt32(8, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
encoder.encodeInt32(9, forKey: "_rawValue")
|
||||
if let language = language {
|
||||
encoder.encodeString(language, forKey: "language")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "language")
|
||||
}
|
||||
case let .TextUrl(url):
|
||||
encoder.encodeInt32(10, forKey: "_rawValue")
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
encoder.encodeInt32(11, forKey: "_rawValue")
|
||||
encoder.encodeInt64(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
encoder.encodeInt32(12, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
encoder.encodeInt32(13, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
encoder.encodeInt32(14, forKey: "_rawValue")
|
||||
encoder.encodeBool(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
encoder.encodeInt32(15, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
encoder.encodeInt32(16, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
encoder.encodeInt32(17, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
encoder.encodeInt32(18, forKey: "_rawValue")
|
||||
if let stickerPack = stickerPack {
|
||||
encoder.encodeObject(stickerPack, forKey: "s")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "s")
|
||||
}
|
||||
encoder.encodeInt64(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
encoder.encodeInt32(19, forKey: "_rawValue")
|
||||
encoder.encodeInt32(format.rawValue, forKey: "format")
|
||||
encoder.encodeInt32(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
|
||||
encoder.encodeInt32(type, forKey: "type")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,53 +279,57 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
try container.encode(Int32(self.range.lowerBound), forKey: "start")
|
||||
try container.encode(Int32(self.range.upperBound), forKey: "end")
|
||||
switch self.type {
|
||||
case .Unknown:
|
||||
try container.encode(0 as Int32, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
try container.encode(1 as Int32, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
try container.encode(2 as Int32, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
try container.encode(3 as Int32, forKey: "_rawValue")
|
||||
case .Url:
|
||||
try container.encode(4 as Int32, forKey: "_rawValue")
|
||||
case .Email:
|
||||
try container.encode(5 as Int32, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
try container.encode(6 as Int32, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
try container.encode(7 as Int32, forKey: "_rawValue")
|
||||
case .Code:
|
||||
try container.encode(8 as Int32, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
try container.encode(9 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(language, forKey: "language")
|
||||
case let .TextUrl(url):
|
||||
try container.encode(10 as Int32, forKey: "_rawValue")
|
||||
try container.encode(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
try container.encode(11 as Int32, forKey: "_rawValue")
|
||||
try container.encode(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
try container.encode(12 as Int32, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
try container.encode(13 as Int32, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
try container.encode(14 as Int32, forKey: "_rawValue")
|
||||
try container.encode(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
try container.encode(15 as Int32, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
try container.encode(16 as Int32, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
try container.encode(17 as Int32, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
try container.encode(18 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(stickerPack, forKey: "s")
|
||||
try container.encode(fileId, forKey: "f")
|
||||
case let .Custom(type):
|
||||
try container.encode(Int32.max as Int32, forKey: "_rawValue")
|
||||
try container.encode(type as Int32, forKey: "type")
|
||||
case .Unknown:
|
||||
try container.encode(0 as Int32, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
try container.encode(1 as Int32, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
try container.encode(2 as Int32, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
try container.encode(3 as Int32, forKey: "_rawValue")
|
||||
case .Url:
|
||||
try container.encode(4 as Int32, forKey: "_rawValue")
|
||||
case .Email:
|
||||
try container.encode(5 as Int32, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
try container.encode(6 as Int32, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
try container.encode(7 as Int32, forKey: "_rawValue")
|
||||
case .Code:
|
||||
try container.encode(8 as Int32, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
try container.encode(9 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(language, forKey: "language")
|
||||
case let .TextUrl(url):
|
||||
try container.encode(10 as Int32, forKey: "_rawValue")
|
||||
try container.encode(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
try container.encode(11 as Int32, forKey: "_rawValue")
|
||||
try container.encode(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
try container.encode(12 as Int32, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
try container.encode(13 as Int32, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
try container.encode(14 as Int32, forKey: "_rawValue")
|
||||
try container.encode(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
try container.encode(15 as Int32, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
try container.encode(16 as Int32, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
try container.encode(17 as Int32, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
try container.encode(18 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(stickerPack, forKey: "s")
|
||||
try container.encode(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
try container.encode(19 as Int32, forKey: "_rawValue")
|
||||
try container.encode(format.rawValue, forKey: "format")
|
||||
try container.encode(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
try container.encode(Int32.max as Int32, forKey: "_rawValue")
|
||||
try container.encode(type as Int32, forKey: "type")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3594,6 +3594,8 @@ private func serializeGroupCallMessage(randomId: Int64, text: String, entities:
|
|||
case let .CustomEmoji(_, fileId):
|
||||
entityDict["_"] = "messageEntityCustomEmoji"
|
||||
entityDict["document_id"] = "\(fileId)"
|
||||
case .FormattedDate:
|
||||
return nil
|
||||
case .Custom:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue