mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Update API
This commit is contained in:
@@ -8,13 +8,11 @@ private class AdMessagesHistoryContextImpl {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case opaqueId
|
||||
case messageType
|
||||
case displayAvatar
|
||||
case title
|
||||
case text
|
||||
case textEntities
|
||||
case media
|
||||
case target
|
||||
case messageId
|
||||
case startParam
|
||||
case url
|
||||
case buttonText
|
||||
case sponsorInfo
|
||||
case additionalInfo
|
||||
@@ -26,147 +24,14 @@ private class AdMessagesHistoryContextImpl {
|
||||
case recommended = 1
|
||||
}
|
||||
|
||||
enum Target: Equatable, Codable {
|
||||
enum DecodingError: Error {
|
||||
case generic
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case peer
|
||||
case invite
|
||||
case webPage
|
||||
case botApp
|
||||
}
|
||||
|
||||
struct Invite: Equatable, Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case title
|
||||
case joinHash
|
||||
case nameColor
|
||||
case image
|
||||
case peer
|
||||
}
|
||||
|
||||
var title: String
|
||||
var joinHash: String
|
||||
var nameColor: PeerNameColor?
|
||||
var image: TelegramMediaImage?
|
||||
var peer: Peer?
|
||||
|
||||
init(title: String, joinHash: String, nameColor: PeerNameColor?, image: TelegramMediaImage?, peer: Peer?) {
|
||||
self.title = title
|
||||
self.joinHash = joinHash
|
||||
self.nameColor = nameColor
|
||||
self.image = image
|
||||
self.peer = peer
|
||||
}
|
||||
|
||||
static func ==(lhs: Invite, rhs: Invite) -> Bool {
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
if lhs.joinHash != rhs.joinHash {
|
||||
return false
|
||||
}
|
||||
if lhs.nameColor != rhs.nameColor {
|
||||
return false
|
||||
}
|
||||
if lhs.image != rhs.image {
|
||||
return false
|
||||
}
|
||||
if !arePeersEqual(lhs.peer, rhs.peer) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.title = try container.decode(String.self, forKey: .title)
|
||||
self.joinHash = try container.decode(String.self, forKey: .joinHash)
|
||||
self.nameColor = try container.decodeIfPresent(Int32.self, forKey: .nameColor).flatMap { PeerNameColor(rawValue: $0) }
|
||||
self.image = (try container.decodeIfPresent(Data.self, forKey: .image)).flatMap { data in
|
||||
return TelegramMediaImage(decoder: PostboxDecoder(buffer: MemoryBuffer(data: data)))
|
||||
}
|
||||
self.peer = (try container.decodeIfPresent(Data.self, forKey: .peer)).flatMap { data in
|
||||
return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Peer
|
||||
}
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.title, forKey: .title)
|
||||
try container.encode(self.joinHash, forKey: .joinHash)
|
||||
try container.encodeIfPresent(self.nameColor?.rawValue, forKey: .nameColor)
|
||||
try container.encodeIfPresent(self.image.flatMap { image in
|
||||
let encoder = PostboxEncoder()
|
||||
image.encode(encoder)
|
||||
return encoder.makeData()
|
||||
}, forKey: .image)
|
||||
try container.encodeIfPresent(self.peer.flatMap { peer in
|
||||
let encoder = PostboxEncoder()
|
||||
encoder.encodeRootObject(peer)
|
||||
return encoder.makeData()
|
||||
}, forKey: .peer)
|
||||
}
|
||||
}
|
||||
|
||||
struct WebPage: Equatable, Codable {
|
||||
var title: String
|
||||
var url: String
|
||||
var photo: TelegramMediaImage?
|
||||
}
|
||||
|
||||
case peer(PeerId)
|
||||
case invite(Invite)
|
||||
case webPage(WebPage)
|
||||
case botApp(PeerId, BotApp)
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if let botApp = try container.decodeIfPresent(BotApp.self, forKey: .botApp), let peer = try container.decodeIfPresent(Int64.self, forKey: .peer) {
|
||||
self = .botApp(PeerId(peer), botApp)
|
||||
} else if let peer = try container.decodeIfPresent(Int64.self, forKey: .peer) {
|
||||
self = .peer(PeerId(peer))
|
||||
} else if let invite = try container.decodeIfPresent(Invite.self, forKey: .invite) {
|
||||
self = .invite(invite)
|
||||
} else if let webPage = try container.decodeIfPresent(WebPage.self, forKey: .webPage) {
|
||||
self = .webPage(webPage)
|
||||
} else {
|
||||
throw DecodingError.generic
|
||||
}
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
switch self {
|
||||
case let .peer(peerId):
|
||||
try container.encode(peerId.toInt64(), forKey: .peer)
|
||||
case let .invite(invite):
|
||||
try container.encode(invite, forKey: .invite)
|
||||
case let .webPage(webPage):
|
||||
try container.encode(webPage, forKey: .webPage)
|
||||
case let .botApp(peerId, botApp):
|
||||
try container.encode(peerId.toInt64(), forKey: .peer)
|
||||
try container.encode(botApp, forKey: .botApp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public let opaqueId: Data
|
||||
public let messageType: MessageType
|
||||
public let displayAvatar: Bool
|
||||
public let title: String
|
||||
public let text: String
|
||||
public let textEntities: [MessageTextEntity]
|
||||
public let media: [Media]
|
||||
public let target: Target
|
||||
public let messageId: MessageId?
|
||||
public let startParam: String?
|
||||
public let buttonText: String?
|
||||
public let url: String
|
||||
public let buttonText: String
|
||||
public let sponsorInfo: String?
|
||||
public let additionalInfo: String?
|
||||
public let canReport: Bool
|
||||
@@ -174,27 +39,23 @@ private class AdMessagesHistoryContextImpl {
|
||||
public init(
|
||||
opaqueId: Data,
|
||||
messageType: MessageType,
|
||||
displayAvatar: Bool,
|
||||
title: String,
|
||||
text: String,
|
||||
textEntities: [MessageTextEntity],
|
||||
media: [Media],
|
||||
target: Target,
|
||||
messageId: MessageId?,
|
||||
startParam: String?,
|
||||
buttonText: String?,
|
||||
url: String,
|
||||
buttonText: String,
|
||||
sponsorInfo: String?,
|
||||
additionalInfo: String?,
|
||||
canReport: Bool
|
||||
) {
|
||||
self.opaqueId = opaqueId
|
||||
self.messageType = messageType
|
||||
self.displayAvatar = displayAvatar
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.textEntities = textEntities
|
||||
self.media = media
|
||||
self.target = target
|
||||
self.messageId = messageId
|
||||
self.startParam = startParam
|
||||
self.url = url
|
||||
self.buttonText = buttonText
|
||||
self.sponsorInfo = sponsorInfo
|
||||
self.additionalInfo = additionalInfo
|
||||
@@ -212,8 +73,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
self.messageType = .sponsored
|
||||
}
|
||||
|
||||
self.displayAvatar = try container.decodeIfPresent(Bool.self, forKey: .displayAvatar) ?? false
|
||||
|
||||
self.title = try container.decode(String.self, forKey: .title)
|
||||
self.text = try container.decode(String.self, forKey: .text)
|
||||
self.textEntities = try container.decode([MessageTextEntity].self, forKey: .textEntities)
|
||||
|
||||
@@ -222,10 +82,8 @@ private class AdMessagesHistoryContextImpl {
|
||||
return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Media
|
||||
}
|
||||
|
||||
self.target = try container.decode(Target.self, forKey: .target)
|
||||
self.messageId = try container.decodeIfPresent(MessageId.self, forKey: .messageId)
|
||||
self.startParam = try container.decodeIfPresent(String.self, forKey: .startParam)
|
||||
self.buttonText = try container.decodeIfPresent(String.self, forKey: .buttonText)
|
||||
self.url = try container.decode(String.self, forKey: .url)
|
||||
self.buttonText = try container.decode(String.self, forKey: .buttonText)
|
||||
|
||||
self.sponsorInfo = try container.decodeIfPresent(String.self, forKey: .sponsorInfo)
|
||||
self.additionalInfo = try container.decodeIfPresent(String.self, forKey: .additionalInfo)
|
||||
@@ -238,7 +96,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
|
||||
try container.encode(self.opaqueId, forKey: .opaqueId)
|
||||
try container.encode(self.messageType.rawValue, forKey: .messageType)
|
||||
try container.encode(self.displayAvatar, forKey: .displayAvatar)
|
||||
try container.encode(self.title, forKey: .title)
|
||||
try container.encode(self.text, forKey: .text)
|
||||
try container.encode(self.textEntities, forKey: .textEntities)
|
||||
|
||||
@@ -249,10 +107,8 @@ private class AdMessagesHistoryContextImpl {
|
||||
}
|
||||
try container.encode(mediaData, forKey: .media)
|
||||
|
||||
try container.encode(self.target, forKey: .target)
|
||||
try container.encodeIfPresent(self.messageId, forKey: .messageId)
|
||||
try container.encodeIfPresent(self.startParam, forKey: .startParam)
|
||||
try container.encodeIfPresent(self.buttonText, forKey: .buttonText)
|
||||
try container.encode(self.url, forKey: .url)
|
||||
try container.encode(self.buttonText, forKey: .buttonText)
|
||||
|
||||
try container.encodeIfPresent(self.sponsorInfo, forKey: .sponsorInfo)
|
||||
try container.encodeIfPresent(self.additionalInfo, forKey: .additionalInfo)
|
||||
@@ -267,6 +123,9 @@ private class AdMessagesHistoryContextImpl {
|
||||
if lhs.messageType != rhs.messageType {
|
||||
return false
|
||||
}
|
||||
if lhs.title != rhs.title {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
@@ -281,13 +140,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if lhs.target != rhs.target {
|
||||
return false
|
||||
}
|
||||
if lhs.messageId != rhs.messageId {
|
||||
return false
|
||||
}
|
||||
if lhs.startParam != rhs.startParam {
|
||||
if lhs.url != rhs.url {
|
||||
return false
|
||||
}
|
||||
if lhs.buttonText != rhs.buttonText {
|
||||
@@ -308,17 +161,6 @@ private class AdMessagesHistoryContextImpl {
|
||||
func toMessage(peerId: PeerId, transaction: Transaction) -> Message? {
|
||||
var attributes: [MessageAttribute] = []
|
||||
|
||||
let target: AdMessageAttribute.MessageTarget
|
||||
switch self.target {
|
||||
case let .peer(peerId):
|
||||
target = .peer(id: peerId, message: self.messageId, startParam: self.startParam)
|
||||
case let .invite(invite):
|
||||
target = .join(title: invite.title, joinHash: invite.joinHash, peer: invite.peer.flatMap(EnginePeer.init))
|
||||
case let .webPage(webPage):
|
||||
target = .webPage(title: webPage.title, url: webPage.url)
|
||||
case let .botApp(peerId, botApp):
|
||||
target = .botApp(peerId: peerId, app: botApp, startParam: self.startParam)
|
||||
}
|
||||
let mappedMessageType: AdMessageAttribute.MessageType
|
||||
switch self.messageType {
|
||||
case .sponsored:
|
||||
@@ -326,7 +168,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
case .recommended:
|
||||
mappedMessageType = .recommended
|
||||
}
|
||||
attributes.append(AdMessageAttribute(opaqueId: self.opaqueId, messageType: mappedMessageType, displayAvatar: self.displayAvatar && !self.canReport, target: target, buttonText: self.buttonText, sponsorInfo: self.sponsorInfo, additionalInfo: self.additionalInfo, canReport: self.canReport))
|
||||
attributes.append(AdMessageAttribute(opaqueId: self.opaqueId, messageType: mappedMessageType, url: self.url, buttonText: self.buttonText, sponsorInfo: self.sponsorInfo, additionalInfo: self.additionalInfo, canReport: self.canReport))
|
||||
if !self.textEntities.isEmpty {
|
||||
let attribute = TextEntitiesMessageAttribute(entities: self.textEntities)
|
||||
attributes.append(attribute)
|
||||
@@ -338,81 +180,35 @@ private class AdMessagesHistoryContextImpl {
|
||||
messagePeers[peer.id] = peer
|
||||
}
|
||||
|
||||
let author: Peer
|
||||
switch self.target {
|
||||
case let .peer(peerId), let .botApp(peerId, _):
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
author = peer
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .invite(invite):
|
||||
author = TelegramChannel(
|
||||
id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)),
|
||||
accessHash: nil,
|
||||
title: invite.title,
|
||||
username: nil,
|
||||
photo: [],
|
||||
creationDate: 0,
|
||||
version: 0,
|
||||
participationStatus: .left,
|
||||
info: .broadcast(TelegramChannelBroadcastInfo(flags: [])),
|
||||
flags: [],
|
||||
restrictionInfo: nil,
|
||||
adminRights: nil,
|
||||
bannedRights: nil,
|
||||
defaultBannedRights: nil,
|
||||
usernames: [],
|
||||
storiesHidden: nil,
|
||||
nameColor: invite.nameColor,
|
||||
backgroundEmojiId: nil,
|
||||
profileColor: nil,
|
||||
profileBackgroundEmojiId: nil,
|
||||
emojiStatus: nil,
|
||||
approximateBoostLevel: nil
|
||||
)
|
||||
case let .webPage(webPage):
|
||||
author = TelegramChannel(
|
||||
id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)),
|
||||
accessHash: nil,
|
||||
title: webPage.title,
|
||||
username: nil,
|
||||
photo: webPage.photo?.representations ?? [],
|
||||
creationDate: 0,
|
||||
version: 0,
|
||||
participationStatus: .left,
|
||||
info: .broadcast(TelegramChannelBroadcastInfo(flags: [])),
|
||||
flags: [],
|
||||
restrictionInfo: nil,
|
||||
adminRights: nil,
|
||||
bannedRights: nil,
|
||||
defaultBannedRights: nil,
|
||||
usernames: [],
|
||||
storiesHidden: nil,
|
||||
nameColor: .blue,
|
||||
backgroundEmojiId: nil,
|
||||
profileColor: nil,
|
||||
profileBackgroundEmojiId: nil,
|
||||
emojiStatus: nil,
|
||||
approximateBoostLevel: nil
|
||||
)
|
||||
}
|
||||
|
||||
let author: Peer = TelegramChannel(
|
||||
id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)),
|
||||
accessHash: nil,
|
||||
title: self.title,
|
||||
username: nil,
|
||||
photo: [],
|
||||
creationDate: 0,
|
||||
version: 0,
|
||||
participationStatus: .left,
|
||||
info: .broadcast(TelegramChannelBroadcastInfo(flags: [])),
|
||||
flags: [],
|
||||
restrictionInfo: nil,
|
||||
adminRights: nil,
|
||||
bannedRights: nil,
|
||||
defaultBannedRights: nil,
|
||||
usernames: [],
|
||||
storiesHidden: nil,
|
||||
nameColor: .blue,
|
||||
backgroundEmojiId: nil,
|
||||
profileColor: nil,
|
||||
profileBackgroundEmojiId: nil,
|
||||
emojiStatus: nil,
|
||||
approximateBoostLevel: nil
|
||||
)
|
||||
messagePeers[author.id] = author
|
||||
|
||||
let messageHash = (self.text.hashValue &+ 31 &* peerId.hashValue) &* 31 &+ author.id.hashValue
|
||||
let messageStableVersion = UInt32(bitPattern: Int32(truncatingIfNeeded: messageHash))
|
||||
|
||||
var media: [Media] = self.media
|
||||
if media.isEmpty {
|
||||
if case let .invite(invite) = self.target, let image = invite.image {
|
||||
media.append(image)
|
||||
} else if self.displayAvatar && self.canReport, let profileImage = author.smallProfileImage {
|
||||
media.append(TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [profileImage], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Message(
|
||||
stableId: 0,
|
||||
stableVersion: messageStableVersion,
|
||||
@@ -431,7 +227,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
author: author,
|
||||
text: self.text,
|
||||
attributes: attributes,
|
||||
media: media,
|
||||
media: self.media,
|
||||
peers: messagePeers,
|
||||
associatedMessages: SimpleDictionary<MessageId, Message>(),
|
||||
associatedMessageIds: [],
|
||||
@@ -612,100 +408,30 @@ private class AdMessagesHistoryContextImpl {
|
||||
|
||||
for message in messages {
|
||||
switch message {
|
||||
case let .sponsoredMessage(flags, randomId, fromId, chatInvite, chatInviteHash, channelPost, startParam, webPage, botApp, message, entities, buttonText, sponsorInfo, additionalInfo):
|
||||
case let .sponsoredMessage(flags, randomId, url, title, message, entities, photo, buttonText, sponsorInfo, additionalInfo):
|
||||
var parsedEntities: [MessageTextEntity] = []
|
||||
if let entities = entities {
|
||||
parsedEntities = messageTextEntitiesFromApiEntities(entities)
|
||||
}
|
||||
|
||||
let isRecommended = (flags & (1 << 5)) != 0
|
||||
var displayAvatar = (flags & (1 << 6)) != 0
|
||||
let canReport = (flags & (1 << 12)) != 0
|
||||
|
||||
var target: CachedMessage.Target?
|
||||
if let fromId = fromId {
|
||||
if let botApp = botApp, let app = BotApp(apiBotApp: botApp) {
|
||||
target = .botApp(fromId.peerId, app)
|
||||
} else {
|
||||
target = .peer(fromId.peerId)
|
||||
}
|
||||
} else if let webPage = webPage {
|
||||
switch webPage {
|
||||
case let .sponsoredWebPage(_, url, siteName, photo):
|
||||
let photo = photo.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
target = .webPage(CachedMessage.Target.WebPage(title: siteName, url: url, photo: photo))
|
||||
}
|
||||
} else if let chatInvite = chatInvite, let chatInviteHash = chatInviteHash {
|
||||
switch chatInvite {
|
||||
case let .chatInvite(flags, title, _, photo, participantsCount, participants, nameColor):
|
||||
let image = telegramMediaImageFromApiPhoto(photo)
|
||||
let flags: ExternalJoiningChatState.Invite.Flags = .init(isChannel: (flags & (1 << 0)) != 0, isBroadcast: (flags & (1 << 1)) != 0, isPublic: (flags & (1 << 2)) != 0, isMegagroup: (flags & (1 << 3)) != 0, requestNeeded: (flags & (1 << 6)) != 0, isVerified: (flags & (1 << 7)) != 0, isScam: (flags & (1 << 8)) != 0, isFake: (flags & (1 << 9)) != 0)
|
||||
|
||||
let _ = flags
|
||||
let _ = participantsCount
|
||||
let _ = participants
|
||||
|
||||
target = .invite(CachedMessage.Target.Invite(
|
||||
title: title,
|
||||
joinHash: chatInviteHash,
|
||||
nameColor: PeerNameColor(rawValue: nameColor),
|
||||
image: displayAvatar ? image : nil,
|
||||
peer: nil
|
||||
))
|
||||
|
||||
displayAvatar = false
|
||||
case let .chatInvitePeek(chat, _):
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
target = .invite(CachedMessage.Target.Invite(
|
||||
title: peer.debugDisplayTitle,
|
||||
joinHash: chatInviteHash,
|
||||
nameColor: peer.nameColor,
|
||||
image: nil,
|
||||
peer: displayAvatar ? peer : nil
|
||||
))
|
||||
}
|
||||
|
||||
displayAvatar = false
|
||||
case let .chatInviteAlready(chat):
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
target = .invite(CachedMessage.Target.Invite(
|
||||
title: peer.debugDisplayTitle,
|
||||
joinHash: chatInviteHash,
|
||||
nameColor: peer.nameColor,
|
||||
image: nil,
|
||||
peer: displayAvatar ? peer : nil
|
||||
))
|
||||
}
|
||||
|
||||
displayAvatar = false
|
||||
}
|
||||
}
|
||||
// else if let botApp = app.flatMap({ BotApp(apiBotApp: $0) }) {
|
||||
// target = .botApp(botApp)
|
||||
// }
|
||||
|
||||
var messageId: MessageId?
|
||||
if let fromId = fromId, let channelPost = channelPost {
|
||||
messageId = MessageId(peerId: fromId.peerId, namespace: Namespaces.Message.Cloud, id: channelPost)
|
||||
}
|
||||
let photo = photo.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
|
||||
if let target = target {
|
||||
parsedMessages.append(CachedMessage(
|
||||
opaqueId: randomId.makeData(),
|
||||
messageType: isRecommended ? .recommended : .sponsored,
|
||||
displayAvatar: displayAvatar,
|
||||
text: message,
|
||||
textEntities: parsedEntities,
|
||||
media: [],
|
||||
target: target,
|
||||
messageId: messageId,
|
||||
startParam: startParam,
|
||||
buttonText: buttonText,
|
||||
sponsorInfo: sponsorInfo,
|
||||
additionalInfo: additionalInfo,
|
||||
canReport: canReport
|
||||
))
|
||||
}
|
||||
parsedMessages.append(CachedMessage(
|
||||
opaqueId: randomId.makeData(),
|
||||
messageType: isRecommended ? .recommended : .sponsored,
|
||||
title: title,
|
||||
text: message,
|
||||
textEntities: parsedEntities,
|
||||
media: photo.flatMap { [$0] } ?? [],
|
||||
url: url,
|
||||
buttonText: buttonText,
|
||||
sponsorInfo: sponsorInfo,
|
||||
additionalInfo: additionalInfo,
|
||||
canReport: canReport
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user