Update Ghostgram features

This commit is contained in:
ichmagmaus 812
2026-03-07 18:15:32 +01:00
parent 1a3303b059
commit 24a7ec39d9
902 changed files with 148295 additions and 62348 deletions
@@ -6,7 +6,8 @@ import TelegramApi
func imageRepresentationsForApiChatPhoto(_ photo: Api.ChatPhoto) -> [TelegramMediaImageRepresentation] {
var representations: [TelegramMediaImageRepresentation] = []
switch photo {
case let .chatPhoto(flags, photoId, strippedThumb, dcId):
case let .chatPhoto(chatPhotoData):
let (flags, photoId, strippedThumb, dcId) = (chatPhotoData.flags, chatPhotoData.photoId, chatPhotoData.strippedThumb, chatPhotoData.dcId)
let hasVideo = (flags & (1 << 0)) != 0
let smallResource: TelegramMediaResource
let fullSizeResource: TelegramMediaResource
@@ -24,12 +25,14 @@ func imageRepresentationsForApiChatPhoto(_ photo: Api.ChatPhoto) -> [TelegramMed
func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
switch chat {
case let .chat(flags, id, title, photo, participantsCount, date, version, migratedTo, adminRights, defaultBannedRights):
case let .chat(chatData):
let (flags, id, title, photo, participantsCount, date, version, migratedTo, adminRights, defaultBannedRights) = (chatData.flags, chatData.id, chatData.title, chatData.photo, chatData.participantsCount, chatData.date, chatData.version, chatData.migratedTo, chatData.adminRights, chatData.defaultBannedRights)
let left = (flags & ((1 << 1) | (1 << 2))) != 0
var migrationReference: TelegramGroupToChannelMigrationReference?
if let migratedTo = migratedTo {
switch migratedTo {
case let .inputChannel(channelId, accessHash):
case let .inputChannel(inputChannelData):
let (channelId, accessHash) = (inputChannelData.channelId, inputChannelData.accessHash)
migrationReference = TelegramGroupToChannelMigrationReference(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), accessHash: accessHash)
case .inputChannelEmpty:
break
@@ -57,11 +60,14 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
groupFlags.insert(.copyProtectionEnabled)
}
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: imageRepresentationsForApiChatPhoto(photo), participantCount: Int(participantsCount), role: role, membership: left ? .Left : .Member, flags: groupFlags, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init(apiBannedRights:)), migrationReference: migrationReference, creationDate: date, version: Int(version))
case let .chatEmpty(id):
case let .chatEmpty(chatEmptyData):
let id = chatEmptyData.id
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: "", photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
case let .chatForbidden(id, title):
case let .chatForbidden(chatForbiddenData):
let (id, title) = (chatForbiddenData.id, chatForbiddenData.title)
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: [], participantCount: 0, role: .member, membership: .Removed, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0)
case let .channel(flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumId):
case let .channel(channelData):
let (flags, flags2, id, accessHash, title, username, photo, date, restrictionReason, adminRights, bannedRights, defaultBannedRights, usernames, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumId) = (channelData.flags, channelData.flags2, channelData.id, channelData.accessHash, channelData.title, channelData.username, channelData.photo, channelData.date, channelData.restrictionReason, channelData.adminRights, channelData.bannedRights, channelData.defaultBannedRights, channelData.usernames, channelData.color, channelData.profileColor, channelData.emojiStatus, channelData.level, channelData.subscriptionUntilDate, channelData.botVerificationIcon, channelData.sendPaidMessagesStars, channelData.linkedMonoforumId)
let isMin = (flags & (1 << 12)) != 0
let participationStatus: TelegramChannelParticipationStatus
@@ -172,7 +178,8 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
var backgroundEmojiId: Int64?
if let color = color {
switch color {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
nameColorIndex = color
backgroundEmojiId = backgroundEmojiIdValue
case .peerColorCollectible:
@@ -181,21 +188,23 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
break
}
}
var profileColorIndex: Int32?
var profileBackgroundEmojiId: Int64?
if let profileColor = profileColor {
switch profileColor {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
profileColorIndex = color
profileBackgroundEmojiId = backgroundEmojiIdValue
default:
break
}
}
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColorIndex.flatMap { PeerNameColor(rawValue: $0) }, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), approximateBoostLevel: boostLevel, subscriptionUntilDate: subscriptionUntilDate, verificationIconFileId: verificationIconFileId, sendPaidMessageStars: sendPaidMessageStars.flatMap { StarsAmount(value: $0, nanos: 0) }, linkedMonoforumId: linkedMonoforumId.flatMap { PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value($0)) })
case let .channelForbidden(flags, id, accessHash, title, untilDate):
case let .channelForbidden(channelForbiddenData):
let (flags, id, accessHash, title, untilDate) = (channelForbiddenData.flags, channelForbiddenData.id, channelForbiddenData.accessHash, channelForbiddenData.title, channelForbiddenData.untilDate)
let info: TelegramChannelInfo
if (flags & Int32(1 << 8)) != 0 {
info = .group(TelegramChannelGroupInfo(flags: []))
@@ -203,7 +212,12 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
info = .broadcast(TelegramChannelBroadcastInfo(flags: []))
}
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)
var channelFlags = TelegramChannelFlags()
if (flags & (1 << 10)) != 0 {
channelFlags.insert(.isMonoforum)
}
return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: channelFlags, restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, emojiStatus: nil, approximateBoostLevel: nil, subscriptionUntilDate: nil, verificationIconFileId: nil, sendPaidMessageStars: nil, linkedMonoforumId: nil)
}
}
@@ -211,7 +225,8 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
switch rhs {
case .chat, .chatEmpty, .chatForbidden, .channelForbidden:
return parseTelegramGroupOrChannel(chat: rhs)
case let .channel(flags, flags2, _, accessHash, title, username, photo, _, _, _, _, defaultBannedRights, _, usernames, _, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumIdValue):
case let .channel(channelData):
let (flags, flags2, accessHash, title, username, photo, defaultBannedRights, usernames, color, profileColor, emojiStatus, boostLevel, subscriptionUntilDate, verificationIconFileId, sendPaidMessageStars, linkedMonoforumIdValue) = (channelData.flags, channelData.flags2, channelData.accessHash, channelData.title, channelData.username, channelData.photo, channelData.defaultBannedRights, channelData.usernames, channelData.color, channelData.profileColor, channelData.emojiStatus, channelData.level, channelData.subscriptionUntilDate, channelData.botVerificationIcon, channelData.sendPaidMessagesStars, channelData.linkedMonoforumId)
let isMin = (flags & (1 << 12)) != 0
if accessHash != nil && !isMin {
return parseTelegramGroupOrChannel(chat: rhs)
@@ -257,7 +272,8 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
var backgroundEmojiId: Int64?
if let color = color {
switch color {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
nameColorIndex = color
backgroundEmojiId = backgroundEmojiIdValue
case .peerColorCollectible:
@@ -266,19 +282,20 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? {
break
}
}
var profileColorIndex: Int32?
var profileBackgroundEmojiId: Int64?
if let profileColor = profileColor {
switch profileColor {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
profileColorIndex = color
profileBackgroundEmojiId = backgroundEmojiIdValue
default:
break
}
}
let parsedEmojiStatus = emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:))
let linkedMonoforumId = linkedMonoforumIdValue.flatMap({ PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value($0)) }) ?? lhs.linkedMonoforumId
@@ -20,17 +20,17 @@ extension PeerReference {
var inputPeer: Api.InputPeer {
switch self {
case let .user(id, accessHash):
return .inputPeerUser(userId: id, accessHash: accessHash)
return .inputPeerUser(.init(userId: id, accessHash: accessHash))
case let .group(id):
return .inputPeerChat(chatId: id)
return .inputPeerChat(.init(chatId: id))
case let .channel(id, accessHash):
return .inputPeerChannel(channelId: id, accessHash: accessHash)
return .inputPeerChannel(.init(channelId: id, accessHash: accessHash))
}
}
var inputUser: Api.InputUser? {
if case let .user(id, accessHash) = self {
return .inputUser(userId: id, accessHash: accessHash)
return .inputUser(.init(userId: id, accessHash: accessHash))
} else {
return nil
}
@@ -38,7 +38,7 @@ extension PeerReference {
var inputChannel: Api.InputChannel? {
if case let .channel(id, accessHash) = self {
return .inputChannel(channelId: id, accessHash: accessHash)
return .inputChannel(.init(channelId: id, accessHash: accessHash))
} else {
return nil
}
@@ -48,12 +48,12 @@ extension PeerReference {
func forceApiInputPeer(_ peer: Peer) -> Api.InputPeer? {
switch peer {
case let user as TelegramUser:
return Api.InputPeer.inputPeerUser(userId: user.id.id._internalGetInt64Value(), accessHash: user.accessHash?.value ?? 0)
return Api.InputPeer.inputPeerUser(.init(userId: user.id.id._internalGetInt64Value(), accessHash: user.accessHash?.value ?? 0))
case let group as TelegramGroup:
return Api.InputPeer.inputPeerChat(chatId: group.id.id._internalGetInt64Value())
return Api.InputPeer.inputPeerChat(.init(chatId: group.id.id._internalGetInt64Value()))
case let channel as TelegramChannel:
if let accessHash = channel.accessHash {
return Api.InputPeer.inputPeerChannel(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value)
return Api.InputPeer.inputPeerChannel(.init(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value))
} else {
return nil
}
@@ -65,12 +65,12 @@ func forceApiInputPeer(_ peer: Peer) -> Api.InputPeer? {
func apiInputPeer(_ peer: Peer) -> Api.InputPeer? {
switch peer {
case let user as TelegramUser where user.accessHash != nil:
return Api.InputPeer.inputPeerUser(userId: user.id.id._internalGetInt64Value(), accessHash: user.accessHash!.value)
return Api.InputPeer.inputPeerUser(.init(userId: user.id.id._internalGetInt64Value(), accessHash: user.accessHash!.value))
case let group as TelegramGroup:
return Api.InputPeer.inputPeerChat(chatId: group.id.id._internalGetInt64Value())
return Api.InputPeer.inputPeerChat(.init(chatId: group.id.id._internalGetInt64Value()))
case let channel as TelegramChannel:
if let accessHash = channel.accessHash {
return Api.InputPeer.inputPeerChannel(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value)
return Api.InputPeer.inputPeerChannel(.init(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value))
} else {
return nil
}
@@ -88,7 +88,7 @@ func apiInputPeerOrSelf(_ peer: Peer, accountPeerId: PeerId) -> Api.InputPeer? {
func apiInputChannel(_ peer: Peer) -> Api.InputChannel? {
if let channel = peer as? TelegramChannel, let accessHash = channel.accessHash {
return Api.InputChannel.inputChannel(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value)
return Api.InputChannel.inputChannel(.init(channelId: channel.id.id._internalGetInt64Value(), accessHash: accessHash.value))
} else {
return nil
}
@@ -96,7 +96,7 @@ func apiInputChannel(_ peer: Peer) -> Api.InputChannel? {
func apiInputUser(_ peer: Peer) -> Api.InputUser? {
if let user = peer as? TelegramUser, let accessHash = user.accessHash {
return Api.InputUser.inputUser(userId: user.id.id._internalGetInt64Value(), accessHash: accessHash.value)
return Api.InputUser.inputUser(.init(userId: user.id.id._internalGetInt64Value(), accessHash: accessHash.value))
} else {
return nil
}
@@ -104,7 +104,7 @@ func apiInputUser(_ peer: Peer) -> Api.InputUser? {
func apiInputSecretChat(_ peer: Peer) -> Api.InputEncryptedChat? {
if let chat = peer as? TelegramSecretChat {
return Api.InputEncryptedChat.inputEncryptedChat(chatId: Int32(peer.id.id._internalGetInt64Value()), accessHash: chat.accessHash)
return Api.InputEncryptedChat.inputEncryptedChat(.init(chatId: Int32(peer.id.id._internalGetInt64Value()), accessHash: chat.accessHash))
} else {
return nil
}
@@ -7,7 +7,8 @@ extension BotMenuButton {
switch apiBotMenuButton {
case .botMenuButtonCommands, .botMenuButtonDefault:
self = .commands
case let .botMenuButton(text, url):
case let .botMenuButton(botMenuButtonData):
let (text, url) = (botMenuButtonData.text, botMenuButtonData.url)
self = .webView(text: text, url: url)
}
}
@@ -16,7 +17,8 @@ extension BotMenuButton {
extension BotAppSettings {
init(apiBotAppSettings: Api.BotAppSettings) {
switch apiBotAppSettings {
case let .botAppSettings(_, placeholder, backgroundColor, backgroundDarkColor, headerColor, headerDarkColor):
case let .botAppSettings(botAppSettingsData):
let (_, placeholder, backgroundColor, backgroundDarkColor, headerColor, headerDarkColor) = (botAppSettingsData.flags, botAppSettingsData.placeholderPath, botAppSettingsData.backgroundColor, botAppSettingsData.backgroundDarkColor, botAppSettingsData.headerColor, botAppSettingsData.headerDarkColor)
self.init(
placeholderData: placeholder.flatMap { $0.makeData() },
backgroundColor: backgroundColor,
@@ -31,7 +33,8 @@ extension BotAppSettings {
extension BotVerifierSettings {
init(apiBotVerifierSettings: Api.BotVerifierSettings) {
switch apiBotVerifierSettings {
case let .botVerifierSettings(flags, iconFileId, companyName, customDescription):
case let .botVerifierSettings(botVerifierSettingsData):
let (flags, iconFileId, companyName, customDescription) = (botVerifierSettingsData.flags, botVerifierSettingsData.icon, botVerifierSettingsData.company, botVerifierSettingsData.customDescription)
self.init(
iconFileId: iconFileId,
companyName: companyName,
@@ -45,14 +48,16 @@ extension BotVerifierSettings {
extension BotInfo {
convenience init(apiBotInfo: Api.BotInfo) {
switch apiBotInfo {
case let .botInfo(_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton, privacyPolicyUrl, appSettings, verifierSettings):
case let .botInfo(botInfoData):
let (_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton, privacyPolicyUrl, appSettings, verifierSettings) = (botInfoData.flags, botInfoData.userId, botInfoData.description, botInfoData.descriptionPhoto, botInfoData.descriptionDocument, botInfoData.commands, botInfoData.menuButton, botInfoData.privacyPolicyUrl, botInfoData.appSettings, botInfoData.verifierSettings)
let photo: TelegramMediaImage? = descriptionPhoto.flatMap(telegramMediaImageFromApiPhoto)
let video: TelegramMediaFile? = descriptionDocument.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
var commands: [BotCommand] = []
if let apiCommands = apiCommands {
commands = apiCommands.map { command in
switch command {
case let .botCommand(command, description):
case let .botCommand(botCommandData):
let (command, description) = (botCommandData.command, botCommandData.description)
return BotCommand(text: command, description: description)
}
}
@@ -205,19 +205,25 @@ public final class CachedChannelParticipants: PostboxCoding, Equatable {
extension ChannelParticipant {
init(apiParticipant: Api.ChannelParticipant) {
switch apiParticipant {
case let .channelParticipant(_, userId, date, subscriptionUntilDate):
case let .channelParticipant(channelParticipantData):
let (_, userId, date, subscriptionUntilDate) = (channelParticipantData.flags, channelParticipantData.userId, channelParticipantData.date, channelParticipantData.subscriptionUntilDate)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: subscriptionUntilDate)
case let .channelParticipantCreator(_, userId, adminRights, rank):
case let .channelParticipantCreator(channelParticipantCreatorData):
let (_, userId, adminRights, rank) = (channelParticipantCreatorData.flags, channelParticipantCreatorData.userId, channelParticipantCreatorData.adminRights, channelParticipantCreatorData.rank)
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), canBeEditedByAccountPeer: true), rank: rank)
case let .channelParticipantBanned(flags, userId, restrictedBy, date, bannedRights):
case let .channelParticipantBanned(channelParticipantBannedData):
let (flags, userId, restrictedBy, date, bannedRights) = (channelParticipantBannedData.flags, channelParticipantBannedData.peer, channelParticipantBannedData.kickedBy, channelParticipantBannedData.date, channelParticipantBannedData.bannedRights)
let hasLeft = (flags & (1 << 0)) != 0
let banInfo = ChannelParticipantBannedInfo(rights: TelegramChatBannedRights(apiBannedRights: bannedRights), restrictedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(restrictedBy)), timestamp: date, isMember: !hasLeft)
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil, subscriptionUntilDate: nil)
case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights, rank: rank):
case let .channelParticipantAdmin(channelParticipantAdminData):
let (flags, userId, _, promotedBy, date, adminRights, rank) = (channelParticipantAdminData.flags, channelParticipantAdminData.userId, channelParticipantAdminData.inviterId, channelParticipantAdminData.promotedBy, channelParticipantAdminData.date, channelParticipantAdminData.adminRights, channelParticipantAdminData.rank)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(promotedBy)), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank, subscriptionUntilDate: nil)
case let .channelParticipantSelf(_, userId, _, date, subscriptionUntilDate):
case let .channelParticipantSelf(channelParticipantSelfData):
let (_, userId, _, date, subscriptionUntilDate) = (channelParticipantSelfData.flags, channelParticipantSelfData.userId, channelParticipantSelfData.inviterId, channelParticipantSelfData.date, channelParticipantSelfData.subscriptionUntilDate)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: subscriptionUntilDate)
case let .channelParticipantLeft(userId):
case let .channelParticipantLeft(channelParticipantLeftData):
let (userId) = (channelParticipantLeftData.peer)
self = .member(id: userId.peerId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: nil)
}
}
@@ -6,11 +6,14 @@ import TelegramApi
extension GroupParticipant {
init(apiParticipant: Api.ChatParticipant) {
switch apiParticipant {
case let .chatParticipantCreator(userId):
case let .chatParticipantCreator(chatParticipantCreatorData):
let userId = chatParticipantCreatorData.userId
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))
case let .chatParticipantAdmin(userId, inviterId, date):
case let .chatParticipantAdmin(chatParticipantAdminData):
let (userId, inviterId, date) = (chatParticipantAdminData.userId, chatParticipantAdminData.inviterId, chatParticipantAdminData.date)
self = .admin(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date)
case let .chatParticipant(userId, inviterId, date):
case let .chatParticipant(chatParticipantData):
let (userId, inviterId, date) = (chatParticipantData.userId, chatParticipantData.inviterId, chatParticipantData.date)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date)
}
}
@@ -19,7 +22,8 @@ extension GroupParticipant {
extension CachedGroupParticipants {
convenience init?(apiParticipants: Api.ChatParticipants) {
switch apiParticipants {
case let .chatParticipants(_, participants, version):
case let .chatParticipants(chatParticipantsData):
let (participants, version) = (chatParticipantsData.participants, chatParticipantsData.version)
self.init(participants: participants.map { GroupParticipant(apiParticipant: $0) }, version: version)
case .chatParticipantsForbidden:
return nil
@@ -490,7 +490,8 @@ public final class ChatContextResultCollection: Equatable, Codable {
extension ChatContextResultMessage {
init(apiMessage: Api.BotInlineMessage) {
switch apiMessage {
case let .botInlineMessageMediaAuto(_, message, entities, replyMarkup):
case let .botInlineMessageMediaAuto(botInlineMessageMediaAutoData):
let (_, message, entities, replyMarkup) = (botInlineMessageMediaAutoData.flags, botInlineMessageMediaAutoData.message, botInlineMessageMediaAutoData.entities, botInlineMessageMediaAutoData.replyMarkup)
var parsedEntities: TextEntitiesMessageAttribute?
if let entities = entities, !entities.isEmpty {
parsedEntities = TextEntitiesMessageAttribute(entities: messageTextEntitiesFromApiEntities(entities))
@@ -500,7 +501,8 @@ extension ChatContextResultMessage {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
}
self = .auto(caption: message, entities: parsedEntities, replyMarkup: parsedReplyMarkup)
case let .botInlineMessageText(flags, message, entities, replyMarkup):
case let .botInlineMessageText(botInlineMessageTextData):
let (flags, message, entities, replyMarkup) = (botInlineMessageTextData.flags, botInlineMessageTextData.message, botInlineMessageTextData.entities, botInlineMessageTextData.replyMarkup)
var parsedEntities: TextEntitiesMessageAttribute?
if let entities = entities, !entities.isEmpty {
parsedEntities = TextEntitiesMessageAttribute(entities: messageTextEntitiesFromApiEntities(entities))
@@ -516,28 +518,32 @@ extension ChatContextResultMessage {
isManuallyAdded: false,
isSafe: false
), replyMarkup: parsedReplyMarkup)
case let .botInlineMessageMediaGeo(_, geo, heading, period, proximityNotificationRadius, replyMarkup):
case let .botInlineMessageMediaGeo(botInlineMessageMediaGeoData):
let (_, geo, heading, period, proximityNotificationRadius, replyMarkup) = (botInlineMessageMediaGeoData.flags, botInlineMessageMediaGeoData.geo, botInlineMessageMediaGeoData.heading, botInlineMessageMediaGeoData.period, botInlineMessageMediaGeoData.proximityNotificationRadius, botInlineMessageMediaGeoData.replyMarkup)
let media = telegramMediaMapFromApiGeoPoint(geo, title: nil, address: nil, provider: nil, venueId: nil, venueType: nil, liveBroadcastingTimeout: period, liveProximityNotificationRadius: proximityNotificationRadius, heading: heading)
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
if let replyMarkup = replyMarkup {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
}
self = .mapLocation(media: media, replyMarkup: parsedReplyMarkup)
case let .botInlineMessageMediaVenue(_, geo, title, address, provider, venueId, venueType, replyMarkup):
case let .botInlineMessageMediaVenue(botInlineMessageMediaVenueData):
let (_, geo, title, address, provider, venueId, venueType, replyMarkup) = (botInlineMessageMediaVenueData.flags, botInlineMessageMediaVenueData.geo, botInlineMessageMediaVenueData.title, botInlineMessageMediaVenueData.address, botInlineMessageMediaVenueData.provider, botInlineMessageMediaVenueData.venueId, botInlineMessageMediaVenueData.venueType, botInlineMessageMediaVenueData.replyMarkup)
let media = telegramMediaMapFromApiGeoPoint(geo, title: title, address: address, provider: provider, venueId: venueId, venueType: venueType, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil, heading: nil)
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
if let replyMarkup = replyMarkup {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
}
self = .mapLocation(media: media, replyMarkup: parsedReplyMarkup)
case let .botInlineMessageMediaContact(_, phoneNumber, firstName, lastName, vcard, replyMarkup):
case let .botInlineMessageMediaContact(botInlineMessageMediaContactData):
let (_, phoneNumber, firstName, lastName, vcard, replyMarkup) = (botInlineMessageMediaContactData.flags, botInlineMessageMediaContactData.phoneNumber, botInlineMessageMediaContactData.firstName, botInlineMessageMediaContactData.lastName, botInlineMessageMediaContactData.vcard, botInlineMessageMediaContactData.replyMarkup)
let media = TelegramMediaContact(firstName: firstName, lastName: lastName, phoneNumber: phoneNumber, peerId: nil, vCardData: vcard.isEmpty ? nil : vcard)
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
if let replyMarkup = replyMarkup {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
}
self = .contact(media: media, replyMarkup: parsedReplyMarkup)
case let .botInlineMessageMediaInvoice(flags, title, description, photo, currency, totalAmount, replyMarkup):
case let .botInlineMessageMediaInvoice(botInlineMessageMediaInvoiceData):
let (flags, title, description, photo, currency, totalAmount, replyMarkup) = (botInlineMessageMediaInvoiceData.flags, botInlineMessageMediaInvoiceData.title, botInlineMessageMediaInvoiceData.description, botInlineMessageMediaInvoiceData.photo, botInlineMessageMediaInvoiceData.currency, botInlineMessageMediaInvoiceData.totalAmount, botInlineMessageMediaInvoiceData.replyMarkup)
var parsedFlags = TelegramMediaInvoiceFlags()
if (flags & (1 << 3)) != 0 {
parsedFlags.insert(.isTest)
@@ -550,7 +556,8 @@ extension ChatContextResultMessage {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
}
self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, subscriptionPeriod: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), replyMarkup: parsedReplyMarkup)
case let .botInlineMessageMediaWebPage(flags, message, entities, url, replyMarkup):
case let .botInlineMessageMediaWebPage(botInlineMessageMediaWebPageData):
let (flags, message, entities, url, replyMarkup) = (botInlineMessageMediaWebPageData.flags, botInlineMessageMediaWebPageData.message, botInlineMessageMediaWebPageData.entities, botInlineMessageMediaWebPageData.url, botInlineMessageMediaWebPageData.replyMarkup)
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
if let replyMarkup = replyMarkup {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
@@ -590,9 +597,11 @@ extension ChatContextResultMessage {
extension ChatContextResult {
init(apiResult: Api.BotInlineResult, queryId: Int64) {
switch apiResult {
case let .botInlineResult(_, id, type, title, description, url, thumb, content, sendMessage):
case let .botInlineResult(botInlineResultData):
let (_, id, type, title, description, url, thumb, content, sendMessage) = (botInlineResultData.flags, botInlineResultData.id, botInlineResultData.type, botInlineResultData.title, botInlineResultData.description, botInlineResultData.url, botInlineResultData.thumb, botInlineResultData.content, botInlineResultData.sendMessage)
self = .externalReference(ChatContextResult.ExternalReference(queryId: queryId, id: id, type: type, title: title, description: description, url: url, content: content.flatMap(TelegramMediaWebFile.init), thumbnail: thumb.flatMap(TelegramMediaWebFile.init), message: ChatContextResultMessage(apiMessage: sendMessage)))
case let .botInlineMediaResult(_, id, type, photo, document, title, description, sendMessage):
case let .botInlineMediaResult(botInlineMediaResultData):
let (_, id, type, photo, document, title, description, sendMessage) = (botInlineMediaResultData.flags, botInlineMediaResultData.id, botInlineMediaResultData.type, botInlineMediaResultData.photo, botInlineMediaResultData.document, botInlineMediaResultData.title, botInlineMediaResultData.description, botInlineMediaResultData.sendMessage)
var image: TelegramMediaImage?
var file: TelegramMediaFile?
if let photo = photo, let parsedImage = telegramMediaImageFromApiPhoto(photo) {
@@ -609,7 +618,8 @@ extension ChatContextResult {
extension ChatContextResultSwitchPeer {
init(apiSwitchPeer: Api.InlineBotSwitchPM) {
switch apiSwitchPeer {
case let .inlineBotSwitchPM(text, startParam):
case let .inlineBotSwitchPM(inlineBotSwitchPMData):
let (text, startParam) = (inlineBotSwitchPMData.text, inlineBotSwitchPMData.startParam)
self.init(text: text, startParam: startParam)
}
}
@@ -618,7 +628,8 @@ extension ChatContextResultSwitchPeer {
extension ChatContextResultWebView {
init(apiSwitchWebView: Api.InlineBotWebView) {
switch apiSwitchWebView {
case let .inlineBotWebView(text, url):
case let .inlineBotWebView(inlineBotWebViewData):
let (text, url) = (inlineBotWebViewData.text, inlineBotWebViewData.url)
self.init(text: text, url: url)
}
}
@@ -627,7 +638,8 @@ extension ChatContextResultWebView {
extension ChatContextResultCollection {
convenience init(apiResults: Api.messages.BotResults, botId: PeerId, peerId: PeerId, query: String, geoPoint: (Double, Double)?) {
switch apiResults {
case let .botResults(flags, queryId, nextOffset, switchPm, switchWebView, results, cacheTime, _):
case let .botResults(botResultsData):
let (flags, queryId, nextOffset, switchPm, switchWebView, results, cacheTime, _) = (botResultsData.flags, botResultsData.queryId, botResultsData.nextOffset, botResultsData.switchPm, botResultsData.switchWebview, botResultsData.results, botResultsData.cacheTime, botResultsData.users)
var switchPeer: ChatContextResultSwitchPeer?
if let switchPm = switchPm {
switchPeer = ChatContextResultSwitchPeer(apiSwitchPeer: switchPm)
@@ -28,19 +28,19 @@ public protocol TelegramCloudMediaResourceWithFileReference {
extension CloudFileMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, TelegramCloudMediaResourceWithFileReference {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return Api.InputFileLocation.inputFileLocation(volumeId: self.volumeId, localId: self.localId, secret: self.secret, fileReference: Buffer(data: fileReference ?? Data()))
return Api.InputFileLocation.inputFileLocation(.init(volumeId: self.volumeId, localId: self.localId, secret: self.secret, fileReference: Buffer(data: fileReference ?? Data())))
}
}
extension CloudPhotoSizeMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, TelegramCloudMediaResourceWithFileReference {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return Api.InputFileLocation.inputPhotoFileLocation(id: self.photoId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: self.sizeSpec)
return Api.InputFileLocation.inputPhotoFileLocation(.init(id: self.photoId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: self.sizeSpec))
}
}
extension CloudDocumentSizeMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, TelegramCloudMediaResourceWithFileReference {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return Api.InputFileLocation.inputDocumentFileLocation(id: self.documentId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: self.sizeSpec)
return Api.InputFileLocation.inputDocumentFileLocation(.init(id: self.documentId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: self.sizeSpec))
}
}
@@ -54,7 +54,7 @@ extension CloudPeerPhotoSizeMediaResource: TelegramMultipartFetchableResource {
flags = 1 << 0
}
if let photoId = self.photoId {
return Api.InputFileLocation.inputPeerPhotoFileLocation(flags: flags, peer: peerReference.inputPeer, photoId: photoId)
return Api.InputFileLocation.inputPeerPhotoFileLocation(.init(flags: flags, peer: peerReference.inputPeer, photoId: photoId))
} else {
return nil
}
@@ -64,7 +64,7 @@ extension CloudPeerPhotoSizeMediaResource: TelegramMultipartFetchableResource {
extension CloudStickerPackThumbnailMediaResource: TelegramMultipartFetchableResource {
func apiInputLocation(packReference: StickerPackReference) -> Api.InputFileLocation? {
if let thumbVersion = self.thumbVersion {
return Api.InputFileLocation.inputStickerSetThumb(stickerset: packReference.apiInputStickerSet, thumbVersion: thumbVersion)
return Api.InputFileLocation.inputStickerSetThumb(.init(stickerset: packReference.apiInputStickerSet, thumbVersion: thumbVersion))
} else {
return nil
}
@@ -73,12 +73,12 @@ extension CloudStickerPackThumbnailMediaResource: TelegramMultipartFetchableReso
extension CloudDocumentMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, TelegramCloudMediaResourceWithFileReference {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return Api.InputFileLocation.inputDocumentFileLocation(id: self.fileId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: "")
return Api.InputFileLocation.inputDocumentFileLocation(.init(id: self.fileId, accessHash: self.accessHash, fileReference: Buffer(data: fileReference ?? Data()), thumbSize: ""))
}
}
extension SecretFileMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return .inputEncryptedFileLocation(id: self.fileId, accessHash: self.accessHash)
return .inputEncryptedFileLocation(.init(id: self.fileId, accessHash: self.accessHash))
}
}
@@ -6,7 +6,8 @@ import TelegramApi
extension ExportedInvitation {
init(apiExportedInvite: Api.ExportedChatInvite) {
switch apiExportedInvite {
case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, subscriptionExpired, title, pricing):
case let .chatInviteExported(chatInviteExportedData):
let (flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, subscriptionExpired, title, pricing) = (chatInviteExportedData.flags, chatInviteExportedData.link, chatInviteExportedData.adminId, chatInviteExportedData.date, chatInviteExportedData.startDate, chatInviteExportedData.expireDate, chatInviteExportedData.usageLimit, chatInviteExportedData.usage, chatInviteExportedData.requested, chatInviteExportedData.subscriptionExpired, chatInviteExportedData.title, chatInviteExportedData.subscriptionPricing)
let _ = subscriptionExpired
self = .link(link: link, title: title, isPermanent: (flags & (1 << 5)) != 0, requestApproval: (flags & (1 << 6)) != 0, isRevoked: (flags & (1 << 0)) != 0, adminId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(adminId)), date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: usage, requestedCount: requested, pricing: pricing.flatMap { StarsSubscriptionPricing(apiStarsSubscriptionPricing: $0) })
case .chatInvitePublicJoinRequests:
@@ -6,7 +6,8 @@ import TelegramApi
extension InstantPageCaption {
convenience init(apiCaption: Api.PageCaption) {
switch apiCaption {
case let .pageCaption(text, credit):
case let .pageCaption(pageCaptionData):
let (text, credit) = (pageCaptionData.text, pageCaptionData.credit)
self.init(text: RichText(apiText: text), credit: RichText(apiText: credit))
}
}
@@ -28,18 +29,22 @@ public extension InstantPageListItem {
extension InstantPageListItem {
init(apiListItem: Api.PageListItem) {
switch apiListItem {
case let .pageListItemText(text):
case let .pageListItemText(pageListItemTextData):
let text = pageListItemTextData.text
self = .text(RichText(apiText: text), nil)
case let .pageListItemBlocks(blocks):
case let .pageListItemBlocks(pageListItemBlocksData):
let blocks = pageListItemBlocksData.blocks
self = .blocks(blocks.map({ InstantPageBlock(apiBlock: $0) }), nil)
}
}
init(apiListOrderedItem: Api.PageListOrderedItem) {
switch apiListOrderedItem {
case let .pageListOrderedItemText(num, text):
case let .pageListOrderedItemText(pageListOrderedItemTextData):
let (num, text) = (pageListOrderedItemTextData.num, pageListOrderedItemTextData.text)
self = .text(RichText(apiText: text), num)
case let .pageListOrderedItemBlocks(num, blocks):
case let .pageListOrderedItemBlocks(pageListOrderedItemBlocksData):
let (num, blocks) = (pageListOrderedItemBlocksData.num, pageListOrderedItemBlocksData.blocks)
self = .blocks(blocks.map({ InstantPageBlock(apiBlock: $0) }), num)
}
}
@@ -48,7 +53,8 @@ extension InstantPageListItem {
extension InstantPageTableCell {
convenience init(apiTableCell: Api.PageTableCell) {
switch apiTableCell {
case let .pageTableCell(flags, text, colspan, rowspan):
case let .pageTableCell(pageTableCellData):
let (flags, text, colspan, rowspan) = (pageTableCellData.flags, pageTableCellData.text, pageTableCellData.colspan, pageTableCellData.rowspan)
var alignment = TableHorizontalAlignment.left
if (flags & (1 << 3)) != 0 {
alignment = .center
@@ -69,7 +75,8 @@ extension InstantPageTableCell {
extension InstantPageTableRow {
convenience init(apiTableRow: Api.PageTableRow) {
switch apiTableRow {
case let .pageTableRow(cells):
case let .pageTableRow(pageTableRowData):
let cells = pageTableRowData.cells
self.init(cells: cells.map({ InstantPageTableCell(apiTableCell: $0) }))
}
}
@@ -78,7 +85,8 @@ extension InstantPageTableRow {
extension InstantPageRelatedArticle {
convenience init(apiRelatedArticle: Api.PageRelatedArticle) {
switch apiRelatedArticle {
case let .pageRelatedArticle(_, url, webpageId, title, description, photoId, author, publishedDate):
case let .pageRelatedArticle(pageRelatedArticleData):
let (url, webpageId, title, description, photoId, author, publishedDate) = (pageRelatedArticleData.url, pageRelatedArticleData.webpageId, pageRelatedArticleData.title, pageRelatedArticleData.description, pageRelatedArticleData.photoId, pageRelatedArticleData.author, pageRelatedArticleData.publishedDate)
var posterPhotoId: MediaId?
if let photoId = photoId {
posterPhotoId = MediaId(namespace: Namespaces.Media.CloudImage, id: photoId)
@@ -93,71 +101,99 @@ extension InstantPageBlock {
switch apiBlock {
case .pageBlockUnsupported:
self = .unsupported
case let .pageBlockTitle(text):
case let .pageBlockTitle(pageBlockTitleData):
let text = pageBlockTitleData.text
self = .title(RichText(apiText: text))
case let .pageBlockSubtitle(text):
case let .pageBlockSubtitle(pageBlockSubtitleData):
let text = pageBlockSubtitleData.text
self = .subtitle(RichText(apiText: text))
case let .pageBlockAuthorDate(author, publishedDate):
case let .pageBlockAuthorDate(pageBlockAuthorDateData):
let (author, publishedDate) = (pageBlockAuthorDateData.author, pageBlockAuthorDateData.publishedDate)
self = .authorDate(author: RichText(apiText: author), date: publishedDate)
case let .pageBlockHeader(text):
case let .pageBlockHeader(pageBlockHeaderData):
let text = pageBlockHeaderData.text
self = .header(RichText(apiText: text))
case let .pageBlockSubheader(text):
case let .pageBlockSubheader(pageBlockSubheaderData):
let text = pageBlockSubheaderData.text
self = .subheader(RichText(apiText: text))
case let .pageBlockParagraph(text):
case let .pageBlockParagraph(pageBlockParagraphData):
let text = pageBlockParagraphData.text
self = .paragraph(RichText(apiText: text))
case let .pageBlockPreformatted(text, _):
case let .pageBlockPreformatted(pageBlockPreformattedData):
let text = pageBlockPreformattedData.text
self = .preformatted(RichText(apiText: text))
case let .pageBlockFooter(text):
case let .pageBlockFooter(pageBlockFooterData):
let text = pageBlockFooterData.text
self = .footer(RichText(apiText: text))
case .pageBlockDivider:
self = .divider
case let .pageBlockAnchor(name):
case let .pageBlockAnchor(pageBlockAnchorData):
let name = pageBlockAnchorData.name
self = .anchor(name)
case let .pageBlockBlockquote(text, caption):
case let .pageBlockBlockquote(pageBlockBlockquoteData):
let (text, caption) = (pageBlockBlockquoteData.text, pageBlockBlockquoteData.caption)
self = .blockQuote(text: RichText(apiText: text), caption: RichText(apiText: caption))
case let .pageBlockPullquote(text, caption):
case let .pageBlockPullquote(pageBlockPullquoteData):
let (text, caption) = (pageBlockPullquoteData.text, pageBlockPullquoteData.caption)
self = .pullQuote(text: RichText(apiText: text), caption: RichText(apiText: caption))
case let .pageBlockPhoto(flags, photoId, caption, url, webpageId):
case let .pageBlockPhoto(pageBlockPhotoData):
let (flags, photoId, caption, url, webpageId) = (pageBlockPhotoData.flags, pageBlockPhotoData.photoId, pageBlockPhotoData.caption, pageBlockPhotoData.url, pageBlockPhotoData.webpageId)
var webpageMediaId: MediaId?
if (flags & (1 << 0)) != 0, let webpageId = webpageId, webpageId != 0 {
webpageMediaId = MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId)
}
self = .image(id: MediaId(namespace: Namespaces.Media.CloudImage, id: photoId), caption: InstantPageCaption(apiCaption: caption), url: url, webpageId: webpageMediaId)
case let .pageBlockVideo(flags, videoId, caption):
case let .pageBlockVideo(pageBlockVideoData):
let (flags, videoId, caption) = (pageBlockVideoData.flags, pageBlockVideoData.videoId, pageBlockVideoData.caption)
self = .video(id: MediaId(namespace: Namespaces.Media.CloudFile, id: videoId), caption: InstantPageCaption(apiCaption: caption), autoplay: (flags & (1 << 0)) != 0, loop: (flags & (1 << 1)) != 0)
case let .pageBlockCover(cover):
case let .pageBlockCover(pageBlockCoverData):
let cover = pageBlockCoverData.cover
self = .cover(InstantPageBlock(apiBlock: cover))
case let .pageBlockEmbed(flags, url, html, posterPhotoId, w, h, caption):
case let .pageBlockEmbed(pageBlockEmbedData):
let (flags, url, html, posterPhotoId, w, h, caption) = (pageBlockEmbedData.flags, pageBlockEmbedData.url, pageBlockEmbedData.html, pageBlockEmbedData.posterPhotoId, pageBlockEmbedData.w, pageBlockEmbedData.h, pageBlockEmbedData.caption)
var dimensions: PixelDimensions?
if let w = w, let h = h {
dimensions = PixelDimensions(width: w, height: h)
}
self = .webEmbed(url: url, html: html, dimensions: dimensions, caption: InstantPageCaption(apiCaption: caption), stretchToWidth: (flags & (1 << 0)) != 0, allowScrolling: (flags & (1 << 3)) != 0, coverId: posterPhotoId.flatMap { MediaId(namespace: Namespaces.Media.CloudImage, id: $0) })
case let .pageBlockEmbedPost(url, webpageId, authorPhotoId, author, date, blocks, caption):
case let .pageBlockEmbedPost(pageBlockEmbedPostData):
let (url, webpageId, authorPhotoId, author, date, blocks, caption) = (pageBlockEmbedPostData.url, pageBlockEmbedPostData.webpageId, pageBlockEmbedPostData.authorPhotoId, pageBlockEmbedPostData.author, pageBlockEmbedPostData.date, pageBlockEmbedPostData.blocks, pageBlockEmbedPostData.caption)
self = .postEmbed(url: url, webpageId: webpageId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudWebpage, id: webpageId), avatarId: authorPhotoId == 0 ? nil : MediaId(namespace: Namespaces.Media.CloudImage, id: authorPhotoId), author: author, date: date, blocks: blocks.map({ InstantPageBlock(apiBlock: $0) }), caption: InstantPageCaption(apiCaption: caption))
case let .pageBlockCollage(items, caption):
case let .pageBlockCollage(pageBlockCollageData):
let (items, caption) = (pageBlockCollageData.items, pageBlockCollageData.caption)
self = .collage(items: items.map({ InstantPageBlock(apiBlock: $0) }), caption: InstantPageCaption(apiCaption: caption))
case let .pageBlockSlideshow(items, caption):
case let .pageBlockSlideshow(pageBlockSlideshowData):
let (items, caption) = (pageBlockSlideshowData.items, pageBlockSlideshowData.caption)
self = .slideshow(items: items.map({ InstantPageBlock(apiBlock: $0) }), caption: InstantPageCaption(apiCaption: caption))
case let .pageBlockChannel(channel: apiChat):
case let .pageBlockChannel(pageBlockChannelData):
let apiChat = pageBlockChannelData.channel
self = .channelBanner(parseTelegramGroupOrChannel(chat: apiChat) as? TelegramChannel)
case let .pageBlockAudio(audioId, caption):
case let .pageBlockAudio(pageBlockAudioData):
let (audioId, caption) = (pageBlockAudioData.audioId, pageBlockAudioData.caption)
self = .audio(id: MediaId(namespace: Namespaces.Media.CloudFile, id: audioId), caption: InstantPageCaption(apiCaption: caption))
case let .pageBlockKicker(text):
case let .pageBlockKicker(pageBlockKickerData):
let text = pageBlockKickerData.text
self = .kicker(RichText(apiText: text))
case let .pageBlockTable(flags, title, rows):
case let .pageBlockTable(pageBlockTableData):
let (flags, title, rows) = (pageBlockTableData.flags, pageBlockTableData.title, pageBlockTableData.rows)
self = .table(title: RichText(apiText: title), rows: rows.map({ InstantPageTableRow(apiTableRow: $0) }), bordered: (flags & (1 << 0)) != 0, striped: (flags & (1 << 1)) != 0)
case let .pageBlockList(items):
case let .pageBlockList(pageBlockListData):
let items = pageBlockListData.items
self = .list(items: items.map({ InstantPageListItem(apiListItem: $0) }), ordered: false)
case let .pageBlockOrderedList(items):
case let .pageBlockOrderedList(pageBlockOrderedListData):
let items = pageBlockOrderedListData.items
self = .list(items: items.map({ InstantPageListItem(apiListOrderedItem: $0) }), ordered: true)
case let .pageBlockDetails(flags, blocks, title):
case let .pageBlockDetails(pageBlockDetailsData):
let (flags, blocks, title) = (pageBlockDetailsData.flags, pageBlockDetailsData.blocks, pageBlockDetailsData.title)
self = .details(title: RichText(apiText: title), blocks: blocks.map({ InstantPageBlock(apiBlock: $0) }), expanded: (flags & (1 << 0)) != 0)
case let .pageBlockRelatedArticles(title, articles):
case let .pageBlockRelatedArticles(pageBlockRelatedArticlesData):
let (title, articles) = (pageBlockRelatedArticlesData.title, pageBlockRelatedArticlesData.articles)
self = .relatedArticles(title: RichText(apiText: title), articles: articles.map({ InstantPageRelatedArticle(apiRelatedArticle: $0) }))
case let .pageBlockMap(geo, zoom, w, h, caption):
case let .pageBlockMap(pageBlockMapData):
let (geo, zoom, w, h, caption) = (pageBlockMapData.geo, pageBlockMapData.zoom, pageBlockMapData.w, pageBlockMapData.h, pageBlockMapData.caption)
switch geo {
case let .geoPoint(_, long, lat, _, _):
case let .geoPoint(geoPointData):
let (long, lat) = (geoPointData.long, geoPointData.lat)
self = .map(latitude: lat, longitude: long, zoom: zoom, dimensions: PixelDimensions(width: w, height: h), caption: InstantPageCaption(apiCaption: caption))
default:
self = .unsupported
@@ -176,7 +212,8 @@ extension InstantPage {
let url: String
let views: Int32?
switch apiPage {
case let .page(flags, pageUrl, pageBlocks, pagePhotos, pageDocuments, pageViews):
case let .page(pageData):
let (flags, pageUrl, pageBlocks, pagePhotos, pageDocuments, pageViews) = (pageData.flags, pageData.url, pageData.blocks, pageData.photos, pageData.documents, pageData.views)
url = pageUrl
blocks = pageBlocks
photos = pagePhotos
@@ -6,7 +6,8 @@ import TelegramApi
extension RestrictionRule {
convenience init(apiReason: Api.RestrictionReason) {
switch apiReason {
case let .restrictionReason(platform, reason, text):
case let .restrictionReason(restrictionReasonData):
let (platform, reason, text) = (restrictionReasonData.platform, restrictionReasonData.reason, restrictionReasonData.text)
self.init(platform: platform, reason: reason, text: text)
}
}
@@ -6,8 +6,10 @@ import TelegramApi
extension PeerGeoLocation {
init?(apiLocation: Api.ChannelLocation) {
switch apiLocation {
case let .channelLocation(geopoint, address):
if case let .geoPoint(_, longitude, latitude, _, _) = geopoint {
case let .channelLocation(channelLocationData):
let (geopoint, address) = (channelLocationData.geoPoint, channelLocationData.address)
if case let .geoPoint(geoPointData) = geopoint {
let (longitude, latitude) = (geoPointData.long, geoPointData.lat)
self.init(latitude: latitude, longitude: longitude, address: address)
} else {
return nil
@@ -5,13 +5,15 @@ import TelegramApi
extension ReactionsMessageAttribute {
func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
switch reactions {
case let .messageReactions(flags, results, recentReactions, topReactors):
case let .messageReactions(messageReactionsData):
let (flags, results, recentReactions, topReactors) = (messageReactionsData.flags, messageReactionsData.results, messageReactionsData.recentReactions, messageReactionsData.topReactors)
let min = (flags & (1 << 0)) != 0
let canViewList = (flags & (1 << 2)) != 0
let isTags = (flags & (1 << 3)) != 0
var reactions = results.compactMap { result -> MessageReaction? in
switch result {
case let .reactionCount(_, chosenOrder, reaction, count):
case let .reactionCount(reactionCountData):
let (_, chosenOrder, reaction, count) = (reactionCountData.flags, reactionCountData.chosenOrder, reactionCountData.reaction, reactionCountData.count)
if let reaction = MessageReaction.Reaction(apiReaction: reaction) {
return MessageReaction(value: reaction, count: count, chosenOrder: chosenOrder.flatMap(Int.init))
} else {
@@ -23,7 +25,8 @@ extension ReactionsMessageAttribute {
if let recentReactions = recentReactions {
parsedRecentReactions = recentReactions.compactMap { recentReaction -> ReactionsMessageAttribute.RecentPeer? in
switch recentReaction {
case let .messagePeerReaction(flags, peerId, date, reaction):
case let .messagePeerReaction(messagePeerReactionData):
let (flags, peerId, date, reaction) = (messagePeerReactionData.flags, messagePeerReactionData.peerId, messagePeerReactionData.date, messagePeerReactionData.reaction)
let isLarge = (flags & (1 << 0)) != 0
let isUnseen = (flags & (1 << 1)) != 0
let isMy = (flags & (1 << 2)) != 0
@@ -37,7 +40,7 @@ extension ReactionsMessageAttribute {
} else {
parsedRecentReactions = []
}
if min {
var currentSelectedReactions: [MessageReaction.Reaction: Int] = [:]
for reaction in self.reactions {
@@ -59,7 +62,8 @@ extension ReactionsMessageAttribute {
if let topReactors {
for item in topReactors {
switch item {
case let .messageReactor(flags, peerId, count):
case let .messageReactor(messageReactorData):
let (flags, peerId, count) = (messageReactorData.flags, messageReactorData.peerId, messageReactorData.count)
topPeers.append(ReactionsMessageAttribute.TopPeer(
peerId: peerId?.peerId,
count: count,
@@ -70,7 +74,7 @@ extension ReactionsMessageAttribute {
}
}
}
return ReactionsMessageAttribute(canViewList: canViewList, isTags: isTags, reactions: reactions, recentPeers: parsedRecentReactions, topPeers: topPeers)
}
}
@@ -258,14 +262,16 @@ public func mergedMessageReactions(attributes: [MessageAttribute], isTags: Bool)
extension ReactionsMessageAttribute {
convenience init(apiReactions: Api.MessageReactions) {
switch apiReactions {
case let .messageReactions(flags, results, recentReactions, topReactors):
case let .messageReactions(messageReactionsData):
let (flags, results, recentReactions, topReactors) = (messageReactionsData.flags, messageReactionsData.results, messageReactionsData.recentReactions, messageReactionsData.topReactors)
let canViewList = (flags & (1 << 2)) != 0
let isTags = (flags & (1 << 3)) != 0
let parsedRecentReactions: [ReactionsMessageAttribute.RecentPeer]
if let recentReactions = recentReactions {
parsedRecentReactions = recentReactions.compactMap { recentReaction -> ReactionsMessageAttribute.RecentPeer? in
switch recentReaction {
case let .messagePeerReaction(flags, peerId, date, reaction):
case let .messagePeerReaction(messagePeerReactionData):
let (flags, peerId, date, reaction) = (messagePeerReactionData.flags, messagePeerReactionData.peerId, messagePeerReactionData.date, messagePeerReactionData.reaction)
let isLarge = (flags & (1 << 0)) != 0
let isUnseen = (flags & (1 << 1)) != 0
let isMy = (flags & (1 << 2)) != 0
@@ -279,12 +285,13 @@ extension ReactionsMessageAttribute {
} else {
parsedRecentReactions = []
}
var topPeers: [ReactionsMessageAttribute.TopPeer] = []
if let topReactors {
for item in topReactors {
switch item {
case let .messageReactor(flags, peerId, count):
case let .messageReactor(messageReactorData):
let (flags, peerId, count) = (messageReactorData.flags, messageReactorData.peerId, messageReactorData.count)
topPeers.append(ReactionsMessageAttribute.TopPeer(
peerId: peerId?.peerId,
count: count,
@@ -295,13 +302,14 @@ extension ReactionsMessageAttribute {
}
}
}
self.init(
canViewList: canViewList,
isTags: isTags,
reactions: results.compactMap { result -> MessageReaction? in
switch result {
case let .reactionCount(_, chosenOrder, reaction, count):
case let .reactionCount(reactionCountData):
let (_, chosenOrder, reaction, count) = (reactionCountData.flags, reactionCountData.chosenOrder, reactionCountData.reaction, reactionCountData.count)
if let reaction = MessageReaction.Reaction(apiReaction: reaction) {
return MessageReaction(value: reaction, count: count, chosenOrder: chosenOrder.flatMap(Int.init))
} else {
@@ -26,91 +26,141 @@ extension ReplyMarkupButtonAction.PeerTypes {
extension ReplyMarkupButton {
init(apiButton: Api.KeyboardButton) {
switch apiButton {
case let .keyboardButton(text):
self.init(title: text, titleWhenForwarded: nil, action: .text)
case let .keyboardButtonCallback(flags, text, data):
let memory = malloc(data.size)!
memcpy(memory, data.data, data.size)
let dataBuffer = MemoryBuffer(memory: memory, capacity: data.size, length: data.size, freeWhenDone: true)
self.init(title: text, titleWhenForwarded: nil, action: .callback(requiresPassword: (flags & (1 << 0)) != 0, data: dataBuffer))
case let .keyboardButtonRequestGeoLocation(text):
self.init(title: text, titleWhenForwarded: nil, action: .requestMap)
case let .keyboardButtonRequestPhone(text):
self.init(title: text, titleWhenForwarded: nil, action: .requestPhone)
case let .keyboardButtonSwitchInline(flags, text, query, types):
var peerTypes = ReplyMarkupButtonAction.PeerTypes()
if let types = types {
for type in types {
switch type {
case .inlineQueryPeerTypePM:
peerTypes.insert(.users)
case .inlineQueryPeerTypeBotPM:
peerTypes.insert(.bots)
case .inlineQueryPeerTypeBroadcast:
peerTypes.insert(.channels)
case .inlineQueryPeerTypeChat, .inlineQueryPeerTypeMegagroup:
peerTypes.insert(.groups)
case .inlineQueryPeerTypeSameBotPM:
break
}
case let .keyboardButton(keyboardButtonData):
let text = keyboardButtonData.text
self.init(title: text, titleWhenForwarded: nil, action: .text, style: keyboardButtonData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonCallback(keyboardButtonCallbackData):
let (flags, text, data) = (keyboardButtonCallbackData.flags, keyboardButtonCallbackData.text, keyboardButtonCallbackData.data)
let memory = malloc(data.size)!
memcpy(memory, data.data, data.size)
let dataBuffer = MemoryBuffer(memory: memory, capacity: data.size, length: data.size, freeWhenDone: true)
self.init(title: text, titleWhenForwarded: nil, action: .callback(requiresPassword: (flags & (1 << 0)) != 0, data: dataBuffer), style: keyboardButtonCallbackData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonRequestGeoLocation(keyboardButtonRequestGeoLocationData):
let text = keyboardButtonRequestGeoLocationData.text
self.init(title: text, titleWhenForwarded: nil, action: .requestMap, style: keyboardButtonRequestGeoLocationData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonRequestPhone(keyboardButtonRequestPhoneData):
let text = keyboardButtonRequestPhoneData.text
self.init(title: text, titleWhenForwarded: nil, action: .requestPhone, style: keyboardButtonRequestPhoneData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonSwitchInline(keyboardButtonSwitchInlineData):
let (flags, text, query, types) = (keyboardButtonSwitchInlineData.flags, keyboardButtonSwitchInlineData.text, keyboardButtonSwitchInlineData.query, keyboardButtonSwitchInlineData.peerTypes)
var peerTypes = ReplyMarkupButtonAction.PeerTypes()
if let types = types {
for type in types {
switch type {
case .inlineQueryPeerTypePM:
peerTypes.insert(.users)
case .inlineQueryPeerTypeBotPM:
peerTypes.insert(.bots)
case .inlineQueryPeerTypeBroadcast:
peerTypes.insert(.channels)
case .inlineQueryPeerTypeChat, .inlineQueryPeerTypeMegagroup:
peerTypes.insert(.groups)
case .inlineQueryPeerTypeSameBotPM:
break
}
}
self.init(title: text, titleWhenForwarded: nil, action: .switchInline(samePeer: (flags & (1 << 0)) != 0, query: query, peerTypes: peerTypes))
case let .keyboardButtonUrl(text, url):
self.init(title: text, titleWhenForwarded: nil, action: .url(url))
case let .keyboardButtonGame(text):
self.init(title: text, titleWhenForwarded: nil, action: .openWebApp)
case let .keyboardButtonBuy(text):
self.init(title: text, titleWhenForwarded: nil, action: .payment)
case let .keyboardButtonUrlAuth(_, text, fwdText, url, buttonId):
self.init(title: text, titleWhenForwarded: fwdText, action: .urlAuth(url: url, buttonId: buttonId))
case let .inputKeyboardButtonUrlAuth(_, text, fwdText, url, _):
self.init(title: text, titleWhenForwarded: fwdText, action: .urlAuth(url: url, buttonId: 0))
case let .keyboardButtonRequestPoll(_, quiz, text):
let isQuiz: Bool? = quiz.flatMap { quiz in
if case .boolTrue = quiz {
return true
} else {
return false
}
}
self.init(title: text, titleWhenForwarded: nil, action: .switchInline(samePeer: (flags & (1 << 0)) != 0, query: query, peerTypes: peerTypes), style: keyboardButtonSwitchInlineData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonUrl(keyboardButtonUrlData):
let (text, url) = (keyboardButtonUrlData.text, keyboardButtonUrlData.url)
self.init(title: text, titleWhenForwarded: nil, action: .url(url), style: keyboardButtonUrlData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonGame(keyboardButtonGameData):
let text = keyboardButtonGameData.text
self.init(title: text, titleWhenForwarded: nil, action: .openWebApp, style: keyboardButtonGameData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonBuy(keyboardButtonBuyData):
let text = keyboardButtonBuyData.text
self.init(title: text, titleWhenForwarded: nil, action: .payment, style: keyboardButtonBuyData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonUrlAuth(keyboardButtonUrlAuthData):
let (text, fwdText, url, buttonId) = (keyboardButtonUrlAuthData.text, keyboardButtonUrlAuthData.fwdText, keyboardButtonUrlAuthData.url, keyboardButtonUrlAuthData.buttonId)
self.init(title: text, titleWhenForwarded: fwdText, action: .urlAuth(url: url, buttonId: buttonId), style: keyboardButtonUrlAuthData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .inputKeyboardButtonUrlAuth(inputKeyboardButtonUrlAuthData):
let (text, fwdText, url) = (inputKeyboardButtonUrlAuthData.text, inputKeyboardButtonUrlAuthData.fwdText, inputKeyboardButtonUrlAuthData.url)
self.init(title: text, titleWhenForwarded: fwdText, action: .urlAuth(url: url, buttonId: 0), style: inputKeyboardButtonUrlAuthData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonRequestPoll(keyboardButtonRequestPollData):
let (quiz, text) = (keyboardButtonRequestPollData.quiz, keyboardButtonRequestPollData.text)
let isQuiz: Bool? = quiz.flatMap { quiz in
if case .boolTrue = quiz {
return true
} else {
return false
}
self.init(title: text, titleWhenForwarded: nil, action: .setupPoll(isQuiz: isQuiz))
case let .keyboardButtonUserProfile(text, userId):
self.init(title: text, titleWhenForwarded: nil, action: .openUserProfile(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))))
case let .inputKeyboardButtonUserProfile(text, _):
self.init(title: text, titleWhenForwarded: nil, action: .openUserProfile(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0))))
case let .keyboardButtonWebView(text, url):
self.init(title: text, titleWhenForwarded: nil, action: .openWebView(url: url, simple: false))
case let .keyboardButtonSimpleWebView(text, url):
self.init(title: text, titleWhenForwarded: nil, action: .openWebView(url: url, simple: true))
case let .keyboardButtonRequestPeer(text, buttonId, peerType, maxQuantity), let .inputKeyboardButtonRequestPeer(_, text, buttonId, peerType, maxQuantity):
let mappedPeerType: ReplyMarkupButtonRequestPeerType
switch peerType {
case let .requestPeerTypeUser(_, bot, premium):
mappedPeerType = .user(ReplyMarkupButtonRequestPeerType.User(
isBot: bot.flatMap({ $0 == .boolTrue }),
isPremium: premium.flatMap({ $0 == .boolTrue })
))
case let .requestPeerTypeChat(flags, hasUsername, forum, userAdminRights, botAdminRights):
mappedPeerType = .group(ReplyMarkupButtonRequestPeerType.Group(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
isForum: forum.flatMap({ $0 == .boolTrue }),
botParticipant: (flags & (1 << 5)) != 0,
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
case let .requestPeerTypeBroadcast(flags, hasUsername, userAdminRights, botAdminRights):
mappedPeerType = .channel(ReplyMarkupButtonRequestPeerType.Channel(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
}
self.init(title: text, titleWhenForwarded: nil, action: .requestPeer(peerType: mappedPeerType, buttonId: buttonId, maxQuantity: maxQuantity))
case let .keyboardButtonCopy(text, payload):
self.init(title: text, titleWhenForwarded: nil, action: .copyText(payload: payload))
}
self.init(title: text, titleWhenForwarded: nil, action: .setupPoll(isQuiz: isQuiz), style: keyboardButtonRequestPollData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonUserProfile(keyboardButtonUserProfileData):
let (text, userId) = (keyboardButtonUserProfileData.text, keyboardButtonUserProfileData.userId)
self.init(title: text, titleWhenForwarded: nil, action: .openUserProfile(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))), style: keyboardButtonUserProfileData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .inputKeyboardButtonUserProfile(inputKeyboardButtonUserProfileData):
let text = inputKeyboardButtonUserProfileData.text
self.init(title: text, titleWhenForwarded: nil, action: .openUserProfile(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0))), style: inputKeyboardButtonUserProfileData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonWebView(keyboardButtonWebViewData):
let (text, url) = (keyboardButtonWebViewData.text, keyboardButtonWebViewData.url)
self.init(title: text, titleWhenForwarded: nil, action: .openWebView(url: url, simple: false), style: keyboardButtonWebViewData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonSimpleWebView(keyboardButtonSimpleWebViewData):
let (text, url) = (keyboardButtonSimpleWebViewData.text, keyboardButtonSimpleWebViewData.url)
self.init(title: text, titleWhenForwarded: nil, action: .openWebView(url: url, simple: true), style: keyboardButtonSimpleWebViewData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonRequestPeer(keyboardButtonRequestPeerData):
let (text, buttonId, peerType, maxQuantity) = (keyboardButtonRequestPeerData.text, keyboardButtonRequestPeerData.buttonId, keyboardButtonRequestPeerData.peerType, keyboardButtonRequestPeerData.maxQuantity)
let mappedPeerType: ReplyMarkupButtonRequestPeerType
switch peerType {
case let .requestPeerTypeUser(requestPeerTypeUserData):
let (bot, premium) = (requestPeerTypeUserData.bot, requestPeerTypeUserData.premium)
mappedPeerType = .user(ReplyMarkupButtonRequestPeerType.User(
isBot: bot.flatMap({ $0 == .boolTrue }),
isPremium: premium.flatMap({ $0 == .boolTrue })
))
case let .requestPeerTypeChat(requestPeerTypeChatData):
let (flags, hasUsername, forum, userAdminRights, botAdminRights) = (requestPeerTypeChatData.flags, requestPeerTypeChatData.hasUsername, requestPeerTypeChatData.forum, requestPeerTypeChatData.userAdminRights, requestPeerTypeChatData.botAdminRights)
mappedPeerType = .group(ReplyMarkupButtonRequestPeerType.Group(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
isForum: forum.flatMap({ $0 == .boolTrue }),
botParticipant: (flags & (1 << 5)) != 0,
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
case let .requestPeerTypeBroadcast(requestPeerTypeBroadcastData):
let (flags, hasUsername, userAdminRights, botAdminRights) = (requestPeerTypeBroadcastData.flags, requestPeerTypeBroadcastData.hasUsername, requestPeerTypeBroadcastData.userAdminRights, requestPeerTypeBroadcastData.botAdminRights)
mappedPeerType = .channel(ReplyMarkupButtonRequestPeerType.Channel(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
}
self.init(title: text, titleWhenForwarded: nil, action: .requestPeer(peerType: mappedPeerType, buttonId: buttonId, maxQuantity: maxQuantity), style: keyboardButtonRequestPeerData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .inputKeyboardButtonRequestPeer(inputKeyboardButtonRequestPeerData):
let (text, buttonId, peerType, maxQuantity) = (inputKeyboardButtonRequestPeerData.text, inputKeyboardButtonRequestPeerData.buttonId, inputKeyboardButtonRequestPeerData.peerType, inputKeyboardButtonRequestPeerData.maxQuantity)
let mappedPeerType: ReplyMarkupButtonRequestPeerType
switch peerType {
case let .requestPeerTypeUser(requestPeerTypeUserData):
let (bot, premium) = (requestPeerTypeUserData.bot, requestPeerTypeUserData.premium)
mappedPeerType = .user(ReplyMarkupButtonRequestPeerType.User(
isBot: bot.flatMap({ $0 == .boolTrue }),
isPremium: premium.flatMap({ $0 == .boolTrue })
))
case let .requestPeerTypeChat(requestPeerTypeChatData):
let (flags, hasUsername, forum, userAdminRights, botAdminRights) = (requestPeerTypeChatData.flags, requestPeerTypeChatData.hasUsername, requestPeerTypeChatData.forum, requestPeerTypeChatData.userAdminRights, requestPeerTypeChatData.botAdminRights)
mappedPeerType = .group(ReplyMarkupButtonRequestPeerType.Group(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
isForum: forum.flatMap({ $0 == .boolTrue }),
botParticipant: (flags & (1 << 5)) != 0,
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
case let .requestPeerTypeBroadcast(requestPeerTypeBroadcastData):
let (flags, hasUsername, userAdminRights, botAdminRights) = (requestPeerTypeBroadcastData.flags, requestPeerTypeBroadcastData.hasUsername, requestPeerTypeBroadcastData.userAdminRights, requestPeerTypeBroadcastData.botAdminRights)
mappedPeerType = .channel(ReplyMarkupButtonRequestPeerType.Channel(
isCreator: (flags & (1 << 0)) != 0,
hasUsername: hasUsername.flatMap({ $0 == .boolTrue }),
userAdminRights: userAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:)),
botAdminRights: botAdminRights.flatMap(TelegramChatAdminRights.init(apiAdminRights:))
))
}
self.init(title: text, titleWhenForwarded: nil, action: .requestPeer(peerType: mappedPeerType, buttonId: buttonId, maxQuantity: maxQuantity), style: inputKeyboardButtonRequestPeerData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
case let .keyboardButtonCopy(keyboardButtonCopyData):
let (text, payload) = (keyboardButtonCopyData.text, keyboardButtonCopyData.copyText)
self.init(title: text, titleWhenForwarded: nil, action: .copyText(payload: payload), style: keyboardButtonCopyData.style.flatMap(ReplyMarkupButton.Style.init(apiStyle:)))
}
}
}
@@ -118,7 +168,8 @@ extension ReplyMarkupButton {
extension ReplyMarkupRow {
init(apiRow: Api.KeyboardButtonRow) {
switch apiRow {
case let .keyboardButtonRow(buttons):
case let .keyboardButtonRow(keyboardButtonRowData):
let buttons = keyboardButtonRowData.buttons
self.init(buttons: buttons.map { ReplyMarkupButton(apiButton: $0) })
}
}
@@ -130,7 +181,8 @@ extension ReplyMarkupMessageAttribute {
var flags = ReplyMarkupMessageFlags()
var placeholder: String?
switch apiMarkup {
case let .replyKeyboardMarkup(markupFlags, apiRows, apiPlaceholder):
case let .replyKeyboardMarkup(replyKeyboardMarkupData):
let (markupFlags, apiRows, apiPlaceholder) = (replyKeyboardMarkupData.flags, replyKeyboardMarkupData.rows, replyKeyboardMarkupData.placeholder)
rows = apiRows.map { ReplyMarkupRow(apiRow: $0) }
if (markupFlags & (1 << 0)) != 0 {
flags.insert(.fit)
@@ -145,10 +197,12 @@ extension ReplyMarkupMessageAttribute {
flags.insert(.persistent)
}
placeholder = apiPlaceholder
case let .replyInlineMarkup(apiRows):
case let .replyInlineMarkup(replyInlineMarkupData):
let apiRows = replyInlineMarkupData.rows
rows = apiRows.map { ReplyMarkupRow(apiRow: $0) }
flags.insert(.inline)
case let .replyKeyboardForceReply(forceReplyFlags, apiPlaceholder):
case let .replyKeyboardForceReply(replyKeyboardForceReplyData):
let (forceReplyFlags, apiPlaceholder) = (replyKeyboardForceReplyData.flags, replyKeyboardForceReplyData.placeholder)
if (forceReplyFlags & (1 << 1)) != 0 {
flags.insert(.once)
}
@@ -157,7 +211,8 @@ extension ReplyMarkupMessageAttribute {
}
flags.insert(.setupReply)
placeholder = apiPlaceholder
case let .replyKeyboardHide(hideFlags):
case let .replyKeyboardHide(replyKeyboardHideData):
let hideFlags = replyKeyboardHideData.flags
if (hideFlags & (1 << 2)) != 0 {
flags.insert(.personal)
}
@@ -8,35 +8,50 @@ extension RichText {
switch apiText {
case .textEmpty:
self = .empty
case let .textPlain(text):
case let .textPlain(textPlainData):
let text = textPlainData.text
self = .plain(text)
case let .textBold(text):
case let .textBold(textBoldData):
let text = textBoldData.text
self = .bold(RichText(apiText: text))
case let .textItalic(text):
case let .textItalic(textItalicData):
let text = textItalicData.text
self = .italic(RichText(apiText: text))
case let .textUnderline(text):
case let .textUnderline(textUnderlineData):
let text = textUnderlineData.text
self = .underline(RichText(apiText: text))
case let .textStrike(text):
case let .textStrike(textStrikeData):
let text = textStrikeData.text
self = .strikethrough(RichText(apiText: text))
case let .textFixed(text):
case let .textFixed(textFixedData):
let text = textFixedData.text
self = .fixed(RichText(apiText: text))
case let .textUrl(text, url, webpageId):
case let .textUrl(textUrlData):
let (text, url, webpageId) = (textUrlData.text, textUrlData.url, textUrlData.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):
case let .textEmail(textEmailData):
let (text, email) = (textEmailData.text, textEmailData.email)
self = .email(text: RichText(apiText: text), email: email)
case let .textConcat(texts):
case let .textConcat(textConcatData):
let texts = textConcatData.texts
self = .concat(texts.map({ RichText(apiText: $0) }))
case let .textSubscript(text):
case let .textSubscript(textSubscriptData):
let text = textSubscriptData.text
self = .subscript(RichText(apiText: text))
case let .textSuperscript(text):
case let .textSuperscript(textSuperscriptData):
let text = textSuperscriptData.text
self = .superscript(RichText(apiText: text))
case let .textMarked(text):
case let .textMarked(textMarkedData):
let text = textMarkedData.text
self = .marked(RichText(apiText: text))
case let .textPhone(text, phone):
case let .textPhone(textPhoneData):
let (text, phone) = (textPhoneData.text, textPhoneData.phone)
self = .phone(text: RichText(apiText: text), phone: phone)
case let .textImage(documentId, w, h):
case let .textImage(textImageData):
let (documentId, w, h) = (textImageData.documentId, textImageData.w, textImageData.h)
self = .image(id: MediaId(namespace: Namespaces.Media.CloudFile, id: documentId), dimensions: PixelDimensions(width: w, height: h))
case let .textAnchor(text, name):
case let .textAnchor(textAnchorData):
let (text, name) = (textAnchorData.text, textAnchorData.name)
self = .anchor(text: RichText(apiText: text), name: name)
}
}
@@ -81,6 +81,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
}
}
if isAnimated {
// TODO(swiftgram): refinedTag = [.photoOrVideo, .video, .gif]
refinedTag = .gif
}
if file.isAnimatedSticker {
@@ -128,27 +129,30 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? {
switch messsage {
case let .message(_, _, _, _, _, messagePeerId, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
let chatPeerId = messagePeerId
case let .message(messageData):
let chatPeerId = messageData.peerId
return chatPeerId.peerId
case let .messageEmpty(_, _, peerId):
case let .messageEmpty(messageEmptyData):
let (_, _, peerId) = (messageEmptyData.flags, messageEmptyData.id, messageEmptyData.peerId)
if let peerId = peerId {
return peerId.peerId
} else {
return nil
}
case let .messageService(_, _, _, chatPeerId, _, _, _, _, _, _):
case let .messageService(messageServiceData):
let chatPeerId = messageServiceData.peerId
return chatPeerId.peerId
}
}
func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
switch message {
case let .message(_, _, _, fromId, _, chatPeerId, savedPeerId, fwdHeader, viaBotId, viaBusinessBotId, replyTo, _, _, media, _, entities, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(messageData):
let (fromId, chatPeerId, savedPeerId, fwdHeader, viaBotId, viaBusinessBotId, replyTo, media, entities) = (messageData.fromId, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.replyTo, messageData.media, messageData.entities)
let peerId: PeerId = chatPeerId.peerId
var result = [peerId]
let resolvedFromId = fromId?.peerId ?? chatPeerId.peerId
if resolvedFromId != peerId {
@@ -157,7 +161,8 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
if let fwdHeader = fwdHeader {
switch fwdHeader {
case let .messageFwdHeader(_, fromId, _, _, _, _, savedFromPeer, _, savedFromId, _, _, _):
case let .messageFwdHeader(messageFwdHeaderData):
let (fromId, savedFromPeer, savedFromId) = (messageFwdHeaderData.fromId, messageFwdHeaderData.savedFromPeer, messageFwdHeaderData.savedFromId)
if let fromId = fromId {
result.append(fromId.peerId)
}
@@ -183,7 +188,8 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
if let media = media {
switch media {
case let .messageMediaContact(_, _, _, _, userId):
case let .messageMediaContact(messageMediaContactData):
let userId = messageMediaContactData.userId
if userId != 0 {
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))
}
@@ -195,7 +201,8 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
if let entities = entities {
for entity in entities {
switch entity {
case let .messageEntityMentionName(_, _, userId):
case let .messageEntityMentionName(messageEntityMentionNameData):
let userId = messageEntityMentionNameData.userId
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))
default:
break
@@ -205,7 +212,8 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
if let replyTo = replyTo {
switch replyTo {
case let .messageReplyStoryHeader(peer, _):
case let .messageReplyStoryHeader(messageReplyStoryHeaderData):
let peer = messageReplyStoryHeaderData.peer
let storyPeerId = peer.peerId
if !result.contains(storyPeerId) {
result.append(storyPeerId)
@@ -218,12 +226,13 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
return result
case .messageEmpty:
return []
case let .messageService(_, _, fromId, chatPeerId, savedPeerId, _, _, action, _, _):
case let .messageService(messageServiceData):
let (fromId, chatPeerId, savedPeerId, action) = (messageServiceData.fromId, messageServiceData.peerId, messageServiceData.savedPeerId, messageServiceData.action)
let peerId: PeerId = chatPeerId.peerId
var result = [peerId]
let resolvedFromId = fromId?.peerId ?? chatPeerId.peerId
if resolvedFromId != peerId {
result.append(resolvedFromId)
}
@@ -234,43 +243,60 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
switch action {
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday, .messageActionStarGiftPurchaseOffer, .messageActionStarGiftPurchaseOfferDeclined:
break
case let .messageActionChannelMigrateFrom(_, chatId):
case let .messageActionChannelMigrateFrom(messageActionChannelMigrateFromData):
let chatId = messageActionChannelMigrateFromData.chatId
result.append(PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId)))
case let .messageActionChatAddUser(users):
case let .messageActionChatAddUser(messageActionChatAddUserData):
let users = messageActionChatAddUserData.users
for id in users {
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)))
}
case let .messageActionChatCreate(_, users):
case let .messageActionChatCreate(messageActionChatCreateData):
let users = messageActionChatCreateData.users
for id in users {
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)))
}
case let .messageActionChatDeleteUser(userId):
case let .messageActionChatDeleteUser(messageActionChatDeleteUserData):
let userId = messageActionChatDeleteUserData.userId
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))
case let .messageActionChatJoinedByLink(inviterId):
case let .messageActionChatJoinedByLink(messageActionChatJoinedByLinkData):
let inviterId = messageActionChatJoinedByLinkData.inviterId
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)))
case let .messageActionChatMigrateTo(channelId):
case let .messageActionChatMigrateTo(messageActionChatMigrateToData):
let channelId = messageActionChatMigrateToData.channelId
result.append(PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)))
case let .messageActionGeoProximityReached(fromId, toId, _):
case let .messageActionGeoProximityReached(messageActionGeoProximityReachedData):
let (fromId, toId) = (messageActionGeoProximityReachedData.fromId, messageActionGeoProximityReachedData.toId)
result.append(fromId.peerId)
result.append(toId.peerId)
case let .messageActionInviteToGroupCall(_, userIds):
case let .messageActionInviteToGroupCall(messageActionInviteToGroupCallData):
let userIds = messageActionInviteToGroupCallData.users
for id in userIds {
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)))
}
case let .messageActionRequestedPeer(_, peers):
case let .messageActionRequestedPeer(messageActionRequestedPeerData):
let peers = messageActionRequestedPeerData.peers
result.append(contentsOf: peers.map(\.peerId))
case let .messageActionGiftCode(_, boostPeer, _, _, _, _, _, _, _):
case let .messageActionGiftCode(messageActionGiftCodeData):
let boostPeer = messageActionGiftCodeData.boostPeer
if let boostPeer = boostPeer {
result.append(boostPeer.peerId)
}
case let .messageActionPrizeStars(_, _, _, boostPeer, _):
case let .messageActionPrizeStars(messageActionPrizeStarsData):
let boostPeer = messageActionPrizeStarsData.boostPeer
result.append(boostPeer.peerId)
case let .messageActionPaymentRefunded(_, peer, _, _, _, _):
case let .messageActionPaymentRefunded(messageActionPaymentRefundedData):
let peer = messageActionPaymentRefundedData.peer
result.append(peer.peerId)
case let .messageActionConferenceCall(_, _, _, otherParticipants):
case let .messageActionConferenceCall(messageActionConferenceCallData):
let otherParticipants = messageActionConferenceCallData.otherParticipants
if let otherParticipants {
result.append(contentsOf: otherParticipants.map(\.peerId))
}
case let .messageActionNewCreatorPending(messageActionNewCreatorPending):
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionNewCreatorPending.newCreatorId)))
case let .messageActionChangeCreator(messageActionChangeCreator):
result.append(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionChangeCreator.newCreatorId)))
}
return result
@@ -279,12 +305,14 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: ReferencedReplyMessageIds, generalIds: [MessageId])? {
switch message {
case let .message(_, _, id, _, _, chatPeerId, _, _, _, _, replyTo, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(messageData):
let (id, chatPeerId, replyTo) = (messageData.id, messageData.peerId, messageData.replyTo)
if let replyTo = replyTo {
let peerId: PeerId = chatPeerId.peerId
switch replyTo {
case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId):
case let .messageReplyHeader(messageReplyHeaderData):
let (replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
let _ = replyHeader
let _ = replyMedia
let _ = replyToTopId
@@ -292,7 +320,7 @@ func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: Refere
let _ = quoteEntities
let _ = quoteOffset
let _ = todoItemId
if let replyToMsgId = replyToMsgId {
let targetId = MessageId(peerId: replyToPeerId?.peerId ?? peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)
var replyIds = ReferencedReplyMessageIds()
@@ -305,10 +333,12 @@ func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: Refere
}
case .messageEmpty:
break
case let .messageService(_, id, _, chatPeerId, _, replyHeader, _, _, _, _):
case let .messageService(messageServiceData):
let (id, chatPeerId, replyHeader) = (messageServiceData.id, messageServiceData.peerId, messageServiceData.replyTo)
if let replyHeader = replyHeader {
switch replyHeader {
case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId):
case let .messageReplyHeader(messageReplyHeaderData):
let (replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
let _ = replyHeader
let _ = replyMedia
let _ = replyToTopId
@@ -316,7 +346,7 @@ func apiMessageAssociatedMessageIds(_ message: Api.Message) -> (replyIds: Refere
let _ = quoteEntities
let _ = quoteOffset
let _ = todoItemId
if let replyToMsgId = replyToMsgId {
let targetId = MessageId(peerId: replyToPeerId?.peerId ?? chatPeerId.peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)
var replyIds = ReferencedReplyMessageIds()
@@ -340,7 +370,8 @@ struct ParsedMessageWebpageAttributes {
func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerId: PeerId) -> (media: Media?, expirationTimer: Int32?, nonPremium: Bool?, hasSpoiler: Bool?, webpageAttributes: ParsedMessageWebpageAttributes?, videoTimestamp: Int32?) {
if let media = media {
switch media {
case let .messageMediaPhoto(flags, photo, ttlSeconds):
case let .messageMediaPhoto(messageMediaPhotoData):
let (flags, photo, ttlSeconds) = (messageMediaPhotoData.flags, messageMediaPhotoData.photo, messageMediaPhotoData.ttlSeconds)
if let photo = photo {
if let mediaImage = telegramMediaImageFromApiPhoto(photo) {
return (mediaImage, ttlSeconds, nil, (flags & (1 << 3)) != 0, nil, nil)
@@ -348,20 +379,25 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
} else {
return (TelegramMediaExpiredContent(data: .image), nil, nil, nil, nil, nil)
}
case let .messageMediaContact(phoneNumber, firstName, lastName, vcard, userId):
case let .messageMediaContact(messageMediaContactData):
let (phoneNumber, firstName, lastName, vcard, userId) = (messageMediaContactData.phoneNumber, messageMediaContactData.firstName, messageMediaContactData.lastName, messageMediaContactData.vcard, messageMediaContactData.userId)
let contactPeerId: PeerId? = userId == 0 ? nil : PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
let mediaContact = TelegramMediaContact(firstName: firstName, lastName: lastName, phoneNumber: phoneNumber, peerId: contactPeerId, vCardData: vcard.isEmpty ? nil : vcard)
return (mediaContact, nil, nil, nil, nil, nil)
case let .messageMediaGeo(geo):
case let .messageMediaGeo(messageMediaGeoData):
let geo = messageMediaGeoData.geo
let mediaMap = telegramMediaMapFromApiGeoPoint(geo, title: nil, address: nil, provider: nil, venueId: nil, venueType: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil, heading: nil)
return (mediaMap, nil, nil, nil, nil, nil)
case let .messageMediaVenue(geo, title, address, provider, venueId, venueType):
case let .messageMediaVenue(messageMediaVenueData):
let (geo, title, address, provider, venueId, venueType) = (messageMediaVenueData.geo, messageMediaVenueData.title, messageMediaVenueData.address, messageMediaVenueData.provider, messageMediaVenueData.venueId, messageMediaVenueData.venueType)
let mediaMap = telegramMediaMapFromApiGeoPoint(geo, title: title, address: address, provider: provider, venueId: venueId, venueType: venueType, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil, heading: nil)
return (mediaMap, nil, nil, nil, nil, nil)
case let .messageMediaGeoLive(_, geo, heading, period, proximityNotificationRadius):
case let .messageMediaGeoLive(messageMediaGeoLiveData):
let (geo, heading, period, proximityNotificationRadius) = (messageMediaGeoLiveData.geo, messageMediaGeoLiveData.heading, messageMediaGeoLiveData.period, messageMediaGeoLiveData.proximityNotificationRadius)
let mediaMap = telegramMediaMapFromApiGeoPoint(geo, title: nil, address: nil, provider: nil, venueId: nil, venueType: nil, liveBroadcastingTimeout: period, liveProximityNotificationRadius: proximityNotificationRadius, heading: heading)
return (mediaMap, nil, nil, nil, nil, nil)
case let .messageMediaDocument(flags, document, altDocuments, coverPhoto, videoTimestamp, ttlSeconds):
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) {
return (mediaFile, ttlSeconds, (flags & (1 << 3)) != 0, (flags & (1 << 4)) != 0, nil, videoTimestamp)
@@ -377,7 +413,8 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
}
return (TelegramMediaExpiredContent(data: data), nil, nil, nil, nil, nil)
}
case let .messageMediaWebPage(flags, webpage):
case let .messageMediaWebPage(messageMediaWebPageData):
let (flags, webpage) = (messageMediaWebPageData.flags, messageMediaWebPageData.webpage)
if let mediaWebpage = telegramMediaWebpageFromApiWebpage(webpage) {
var webpageForceLargeMedia: Bool?
if (flags & (1 << 0)) != 0 {
@@ -385,7 +422,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
} else if (flags & (1 << 1)) != 0 {
webpageForceLargeMedia = false
}
return (mediaWebpage, nil, nil, nil, ParsedMessageWebpageAttributes(
forceLargeMedia: webpageForceLargeMedia,
isManuallyAdded: (flags & (1 << 3)) != 0,
@@ -396,9 +433,11 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
return (TelegramMediaUnsupported(), nil, nil, nil, nil, nil)
case .messageMediaEmpty:
break
case let .messageMediaGame(game):
case let .messageMediaGame(messageMediaGameData):
let game = messageMediaGameData.game
return (TelegramMediaGame(apiGame: game), nil, nil, nil, nil, nil)
case let .messageMediaInvoice(flags, title, description, photo, receiptMsgId, currency, totalAmount, startParam, apiExtendedMedia):
case let .messageMediaInvoice(messageMediaInvoiceData):
let (flags, title, description, photo, receiptMsgId, currency, totalAmount, startParam, apiExtendedMedia) = (messageMediaInvoiceData.flags, messageMediaInvoiceData.title, messageMediaInvoiceData.description, messageMediaInvoiceData.photo, messageMediaInvoiceData.receiptMsgId, messageMediaInvoiceData.currency, messageMediaInvoiceData.totalAmount, messageMediaInvoiceData.startParam, messageMediaInvoiceData.extendedMedia)
var parsedFlags = TelegramMediaInvoiceFlags()
if (flags & (1 << 3)) != 0 {
parsedFlags.insert(.isTest)
@@ -407,9 +446,11 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
parsedFlags.insert(.shippingAddressRequested)
}
return (TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: receiptMsgId.flatMap { MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }, currency: currency, totalAmount: totalAmount, startParam: startParam, extendedMedia: apiExtendedMedia.flatMap({ TelegramExtendedMedia(apiExtendedMedia: $0, peerId: peerId) }), subscriptionPeriod: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), nil, nil, nil, nil, nil)
case let .messageMediaPoll(poll, results):
case let .messageMediaPoll(messageMediaPollData):
let (poll, results) = (messageMediaPollData.poll, messageMediaPollData.results)
switch poll {
case let .poll(id, flags, question, answers, closePeriod, _):
case let .poll(pollData):
let (id, flags, question, answers, closePeriod, _) = (pollData.id, pollData.flags, pollData.question, pollData.answers, pollData.closePeriod, pollData.closeDate)
let publicity: TelegramMediaPollPublicity
if (flags & (1 << 1)) != 0 {
publicity = .public
@@ -426,16 +467,19 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
let questionText: String
let questionEntities: [MessageTextEntity]
switch question {
case let .textWithEntities(text, entities):
case let .textWithEntities(textWithEntitiesData):
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
questionText = text
questionEntities = messageTextEntitiesFromApiEntities(entities)
}
return (TelegramMediaPoll(pollId: MediaId(namespace: Namespaces.Media.CloudPoll, id: id), publicity: publicity, kind: kind, text: questionText, textEntities: questionEntities, options: answers.map(TelegramMediaPollOption.init(apiOption:)), correctAnswers: nil, results: TelegramMediaPollResults(apiResults: results), isClosed: (flags & (1 << 0)) != 0, deadlineTimeout: closePeriod), nil, nil, nil, nil, nil)
}
case let .messageMediaToDo(_, todo, completions):
case let .messageMediaToDo(messageMediaToDoData):
let (todo, completions) = (messageMediaToDoData.todo, messageMediaToDoData.completions)
switch todo {
case let .todoList(apiFlags, title, list):
case let .todoList(todoListData):
let (apiFlags, title, list) = (todoListData.flags, todoListData.title, todoListData.list)
var flags: TelegramMediaTodo.Flags = []
if (apiFlags & (1 << 0)) != 0 {
flags.insert(.othersCanAppend)
@@ -443,11 +487,12 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
if (apiFlags & (1 << 1)) != 0 {
flags.insert(.othersCanComplete)
}
let todoText: String
let todoEntities: [MessageTextEntity]
switch title {
case let .textWithEntities(text, entities):
case let .textWithEntities(textWithEntitiesData):
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
todoText = text
todoEntities = messageTextEntitiesFromApiEntities(entities)
}
@@ -457,21 +502,25 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
}
return (TelegramMediaTodo(flags: flags, text: todoText, textEntities: todoEntities, items: list.map(TelegramMediaTodo.Item.init(apiItem:)), completions: todoCompletions), nil, nil, nil, nil, nil)
}
case let .messageMediaDice(_, value, emoticon, apiGameOutcome):
case let .messageMediaDice(messageMediaDiceData):
let (value, emoticon, apiGameOutcome) = (messageMediaDiceData.value, messageMediaDiceData.emoticon, messageMediaDiceData.gameOutcome)
var gameOutcome: TelegramMediaDice.GameOutcome?
var tonAmount: Int64?
switch apiGameOutcome {
case let .emojiGameOutcome(seed, stakeTonAmount, outcomeTonAmount):
case let .emojiGameOutcome(emojiGameOutcomeData):
let (seed, stakeTonAmount, outcomeTonAmount) = (emojiGameOutcomeData.seed, emojiGameOutcomeData.stakeTonAmount, emojiGameOutcomeData.tonAmount)
gameOutcome = TelegramMediaDice.GameOutcome(seed: seed.makeData(), tonAmount: outcomeTonAmount)
tonAmount = stakeTonAmount
default:
break
}
return (TelegramMediaDice(emoji: emoticon, tonAmount: tonAmount, value: value, gameOutcome: gameOutcome), nil, nil, nil, nil, nil)
case let .messageMediaStory(flags, peerId, id, _):
case let .messageMediaStory(messageMediaStoryData):
let (flags, peerId, id) = (messageMediaStoryData.flags, messageMediaStoryData.peer, messageMediaStoryData.id)
let isMention = (flags & (1 << 1)) != 0
return (TelegramMediaStory(storyId: StoryId(peerId: peerId.peerId, id: id), isMention: isMention), nil, nil, nil, nil, nil)
case let .messageMediaGiveaway(apiFlags, channels, countries, prizeDescription, quantity, months, stars, untilDate):
case let .messageMediaGiveaway(messageMediaGiveawayData):
let (apiFlags, channels, countries, prizeDescription, quantity, months, stars, untilDate) = (messageMediaGiveawayData.flags, messageMediaGiveawayData.channels, messageMediaGiveawayData.countriesIso2, messageMediaGiveawayData.prizeDescription, messageMediaGiveawayData.quantity, messageMediaGiveawayData.months, messageMediaGiveawayData.stars, messageMediaGiveawayData.untilDate)
var flags: TelegramMediaGiveaway.Flags = []
if (apiFlags & (1 << 0)) != 0 {
flags.insert(.onlyNewSubscribers)
@@ -485,7 +534,8 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
return (nil, nil, nil, nil, nil, nil)
}
return (TelegramMediaGiveaway(flags: flags, channelPeerIds: channels.map { PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value($0)) }, countries: countries ?? [], quantity: quantity, prize: prize, untilDate: untilDate, prizeDescription: prizeDescription), nil, nil, nil, nil, nil)
case let .messageMediaGiveawayResults(apiFlags, channelId, additionalPeersCount, launchMsgId, winnersCount, unclaimedCount, winners, months, stars, prizeDescription, untilDate):
case let .messageMediaGiveawayResults(messageMediaGiveawayResultsData):
let (apiFlags, channelId, additionalPeersCount, launchMsgId, winnersCount, unclaimedCount, winners, months, stars, prizeDescription, untilDate) = (messageMediaGiveawayResultsData.flags, messageMediaGiveawayResultsData.channelId, messageMediaGiveawayResultsData.additionalPeersCount, messageMediaGiveawayResultsData.launchMsgId, messageMediaGiveawayResultsData.winnersCount, messageMediaGiveawayResultsData.unclaimedCount, messageMediaGiveawayResultsData.winners, messageMediaGiveawayResultsData.months, messageMediaGiveawayResultsData.stars, messageMediaGiveawayResultsData.prizeDescription, messageMediaGiveawayResultsData.untilDate)
var flags: TelegramMediaGiveawayResults.Flags = []
if (apiFlags & (1 << 0)) != 0 {
flags.insert(.onlyNewSubscribers)
@@ -502,9 +552,11 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
return (nil, nil, nil, nil, nil, nil)
}
return (TelegramMediaGiveawayResults(flags: flags, launchMessageId: MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), namespace: Namespaces.Message.Cloud, id: launchMsgId), additionalChannelsCount: additionalPeersCount ?? 0, winnersPeerIds: winners.map { PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) }, winnersCount: winnersCount, unclaimedCount: unclaimedCount, prize: prize, untilDate: untilDate, prizeDescription: prizeDescription), nil, nil, nil, nil, nil)
case let .messageMediaPaidMedia(starsAmount, apiExtendedMedia):
case let .messageMediaPaidMedia(messageMediaPaidMediaData):
let (starsAmount, apiExtendedMedia) = (messageMediaPaidMediaData.starsAmount, messageMediaPaidMediaData.extendedMedia)
return (TelegramMediaPaidContent(amount: starsAmount, extendedMedia: apiExtendedMedia.compactMap({ TelegramExtendedMedia(apiExtendedMedia: $0, peerId: peerId) })), nil, nil, nil, nil, nil)
case let .messageMediaVideoStream(flags, call):
case let .messageMediaVideoStream(messageMediaVideoStreamData):
let (flags, call) = (messageMediaVideoStreamData.flags, messageMediaVideoStreamData.call)
if let call = GroupCallReference(call) {
let kind: TelegramMediaLiveStream.Kind
if (flags & (1 << 0)) != 0 {
@@ -523,7 +575,8 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
func coodinatesFromApiMediaAreaCoordinates(_ coordinates: Api.MediaAreaCoordinates) -> MediaArea.Coordinates {
switch coordinates {
case let .mediaAreaCoordinates(_, x, y, width, height, rotation, radius):
case let .mediaAreaCoordinates(mediaAreaCoordinatesData):
let (_, x, y, width, height, rotation, radius) = (mediaAreaCoordinatesData.flags, mediaAreaCoordinatesData.x, mediaAreaCoordinatesData.y, mediaAreaCoordinatesData.w, mediaAreaCoordinatesData.h, mediaAreaCoordinatesData.rotation, mediaAreaCoordinatesData.radius)
return MediaArea.Coordinates(x: x, y: y, width: width, height: height, rotation: rotation, cornerRadius: radius)
}
}
@@ -532,22 +585,25 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
return nil
case .inputMediaAreaVenue:
return nil
case let .mediaAreaGeoPoint(_, coordinates, geo, address):
case let .mediaAreaGeoPoint(mediaAreaGeoPointData):
let (_, coordinates, geo, address) = (mediaAreaGeoPointData.flags, mediaAreaGeoPointData.coordinates, mediaAreaGeoPointData.geo, mediaAreaGeoPointData.address)
let latitude: Double
let longitude: Double
switch geo {
case let .geoPoint(_, long, lat, _, _):
case let .geoPoint(geoPointData):
let (_, long, lat, _, _) = (geoPointData.flags, geoPointData.long, geoPointData.lat, geoPointData.accessHash, geoPointData.accuracyRadius)
latitude = lat
longitude = long
case .geoPointEmpty:
latitude = 0.0
longitude = 0.0
}
var mappedAddress: MapGeoAddress?
if let address {
switch address {
case let .geoPointAddress(_, countryIso2, state, city, street):
case let .geoPointAddress(geoPointAddressData):
let (_, countryIso2, state, city, street) = (geoPointAddressData.flags, geoPointAddressData.countryIso2, geoPointAddressData.state, geoPointAddressData.city, geoPointAddressData.street)
mappedAddress = MapGeoAddress(
country: countryIso2,
state: state,
@@ -556,7 +612,7 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
)
}
}
return .venue(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), venue: MediaArea.Venue(
latitude: latitude,
longitude: longitude,
@@ -565,11 +621,13 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
queryId: nil,
resultId: nil
))
case let .mediaAreaVenue(coordinates, geo, title, address, provider, venueId, venueType):
case let .mediaAreaVenue(mediaAreaVenueData):
let (coordinates, geo, title, address, provider, venueId, venueType) = (mediaAreaVenueData.coordinates, mediaAreaVenueData.geo, mediaAreaVenueData.title, mediaAreaVenueData.address, mediaAreaVenueData.provider, mediaAreaVenueData.venueId, mediaAreaVenueData.venueType)
let latitude: Double
let longitude: Double
switch geo {
case let .geoPoint(_, long, lat, _, _):
case let .geoPoint(geoPointData):
let (_, long, lat, _, _) = (geoPointData.flags, geoPointData.long, geoPointData.lat, geoPointData.accessHash, geoPointData.accuracyRadius)
latitude = lat
longitude = long
case .geoPointEmpty:
@@ -577,7 +635,8 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
longitude = 0.0
}
return .venue(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), venue: MediaArea.Venue(latitude: latitude, longitude: longitude, venue: MapVenue(title: title, address: address, provider: provider, id: venueId, type: venueType), address: nil, queryId: nil, resultId: nil))
case let .mediaAreaSuggestedReaction(flags, coordinates, reaction):
case let .mediaAreaSuggestedReaction(mediaAreaSuggestedReactionData):
let (flags, coordinates, reaction) = (mediaAreaSuggestedReactionData.flags, mediaAreaSuggestedReactionData.coordinates, mediaAreaSuggestedReactionData.reaction)
if let reaction = MessageReaction.Reaction(apiReaction: reaction) {
var parsedFlags = MediaArea.ReactionFlags()
if (flags & (1 << 0)) != 0 {
@@ -590,13 +649,17 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
} else {
return nil
}
case let .mediaAreaUrl(coordinates, url):
case let .mediaAreaUrl(mediaAreaUrlData):
let (coordinates, url) = (mediaAreaUrlData.coordinates, mediaAreaUrlData.url)
return .link(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), url: url)
case let .mediaAreaChannelPost(coordinates, channelId, messageId):
case let .mediaAreaChannelPost(mediaAreaChannelPostData):
let (coordinates, channelId, messageId) = (mediaAreaChannelPostData.coordinates, mediaAreaChannelPostData.channelId, mediaAreaChannelPostData.msgId)
return .channelMessage(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), messageId: EngineMessage.Id(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), namespace: Namespaces.Message.Cloud, id: messageId))
case let .mediaAreaWeather(coordinates, emoji, temperatureC, color):
case let .mediaAreaWeather(mediaAreaWeatherData):
let (coordinates, emoji, temperatureC, color) = (mediaAreaWeatherData.coordinates, mediaAreaWeatherData.emoji, mediaAreaWeatherData.temperatureC, mediaAreaWeatherData.color)
return .weather(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), emoji: emoji, temperature: temperatureC, color: color)
case let .mediaAreaStarGift(coordinates, slug):
case let .mediaAreaStarGift(mediaAreaStarGiftData):
let (coordinates, slug) = (mediaAreaStarGiftData.coordinates, mediaAreaStarGiftData.slug)
return .starGift(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), slug: slug)
}
}
@@ -609,13 +672,13 @@ func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea], transaction: Transac
if let _ = coordinates.cornerRadius {
flags |= (1 << 0)
}
let inputCoordinates = Api.MediaAreaCoordinates.mediaAreaCoordinates(flags: flags, x: coordinates.x, y: coordinates.y, w: coordinates.width, h: coordinates.height, rotation: coordinates.rotation, radius: coordinates.cornerRadius)
let inputCoordinates = Api.MediaAreaCoordinates.mediaAreaCoordinates(.init(flags: flags, x: coordinates.x, y: coordinates.y, w: coordinates.width, h: coordinates.height, rotation: coordinates.rotation, radius: coordinates.cornerRadius))
switch area {
case let .venue(_, venue):
if let queryId = venue.queryId, let resultId = venue.resultId {
apiMediaAreas.append(.inputMediaAreaVenue(coordinates: inputCoordinates, queryId: queryId, resultId: resultId))
apiMediaAreas.append(.inputMediaAreaVenue(.init(coordinates: inputCoordinates, queryId: queryId, resultId: resultId)))
} else if let venueInfo = venue.venue {
apiMediaAreas.append(.mediaAreaVenue(coordinates: inputCoordinates, geo: .geoPoint(flags: 0, long: venue.longitude, lat: venue.latitude, accessHash: 0, accuracyRadius: nil), title: venueInfo.title, address: venueInfo.address ?? "", provider: venueInfo.provider ?? "", venueId: venueInfo.id ?? "", venueType: venueInfo.type ?? ""))
apiMediaAreas.append(.mediaAreaVenue(.init(coordinates: inputCoordinates, geo: .geoPoint(.init(flags: 0, long: venue.longitude, lat: venue.latitude, accessHash: 0, accuracyRadius: nil)), title: venueInfo.title, address: venueInfo.address ?? "", provider: venueInfo.provider ?? "", venueId: venueInfo.id ?? "", venueType: venueInfo.type ?? "")))
} else {
var flags: Int32 = 0
var inputAddress: Api.GeoPointAddress?
@@ -630,10 +693,10 @@ func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea], transaction: Transac
if let _ = address.street {
addressFlags |= (1 << 2)
}
inputAddress = .geoPointAddress(flags: addressFlags, countryIso2: address.country, state: address.state, city: address.city, street: address.street)
inputAddress = .geoPointAddress(.init(flags: addressFlags, countryIso2: address.country, state: address.state, city: address.city, street: address.street))
flags |= (1 << 0)
}
apiMediaAreas.append(.mediaAreaGeoPoint(flags: flags, coordinates: inputCoordinates, geo: .geoPoint(flags: 0, long: venue.longitude, lat: venue.latitude, accessHash: 0, accuracyRadius: nil), address: inputAddress))
apiMediaAreas.append(.mediaAreaGeoPoint(.init(flags: flags, coordinates: inputCoordinates, geo: .geoPoint(.init(flags: 0, long: venue.longitude, lat: venue.latitude, accessHash: 0, accuracyRadius: nil)), address: inputAddress)))
}
case let .reaction(_, reaction, flags):
var apiFlags: Int32 = 0
@@ -643,17 +706,17 @@ func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea], transaction: Transac
if flags.contains(.isFlipped) {
apiFlags |= (1 << 1)
}
apiMediaAreas.append(.mediaAreaSuggestedReaction(flags: apiFlags, coordinates: inputCoordinates, reaction: reaction.apiReaction))
apiMediaAreas.append(.mediaAreaSuggestedReaction(.init(flags: apiFlags, coordinates: inputCoordinates, reaction: reaction.apiReaction)))
case let .channelMessage(_, messageId):
if let transaction, let peer = transaction.getPeer(messageId.peerId), let inputChannel = apiInputChannel(peer) {
apiMediaAreas.append(.inputMediaAreaChannelPost(coordinates: inputCoordinates, channel: inputChannel, msgId: messageId.id))
apiMediaAreas.append(.inputMediaAreaChannelPost(.init(coordinates: inputCoordinates, channel: inputChannel, msgId: messageId.id)))
}
case let .link(_, url):
apiMediaAreas.append(.mediaAreaUrl(coordinates: inputCoordinates, url: url))
apiMediaAreas.append(.mediaAreaUrl(.init(coordinates: inputCoordinates, url: url)))
case let .weather(_, emoji, temperature, color):
apiMediaAreas.append(.mediaAreaWeather(coordinates: inputCoordinates, emoji: emoji, temperatureC: temperature, color: color))
apiMediaAreas.append(.mediaAreaWeather(.init(coordinates: inputCoordinates, emoji: emoji, temperatureC: temperature, color: color)))
case let .starGift(_, slug):
apiMediaAreas.append(.mediaAreaStarGift(coordinates: inputCoordinates, slug: slug))
apiMediaAreas.append(.mediaAreaStarGift(.init(coordinates: inputCoordinates, slug: slug)))
}
}
return apiMediaAreas
@@ -666,43 +729,62 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
switch entity {
case .messageEntityUnknown, .inputMessageEntityMentionName:
break
case let .messageEntityMention(offset, length):
case let .messageEntityMention(messageEntityMentionData):
let (offset, length) = (messageEntityMentionData.offset, messageEntityMentionData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Mention))
case let .messageEntityHashtag(offset, length):
case let .messageEntityHashtag(messageEntityHashtagData):
let (offset, length) = (messageEntityHashtagData.offset, messageEntityHashtagData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Hashtag))
case let .messageEntityBotCommand(offset, length):
case let .messageEntityBotCommand(messageEntityBotCommandData):
let (offset, length) = (messageEntityBotCommandData.offset, messageEntityBotCommandData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BotCommand))
case let .messageEntityUrl(offset, length):
case let .messageEntityUrl(messageEntityUrlData):
let (offset, length) = (messageEntityUrlData.offset, messageEntityUrlData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Url))
case let .messageEntityEmail(offset, length):
case let .messageEntityEmail(messageEntityEmailData):
let (offset, length) = (messageEntityEmailData.offset, messageEntityEmailData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Email))
case let .messageEntityBold(offset, length):
case let .messageEntityBold(messageEntityBoldData):
let (offset, length) = (messageEntityBoldData.offset, messageEntityBoldData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Bold))
case let .messageEntityItalic(offset, length):
case let .messageEntityItalic(messageEntityItalicData):
let (offset, length) = (messageEntityItalicData.offset, messageEntityItalicData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Italic))
case let .messageEntityCode(offset, length):
case let .messageEntityCode(messageEntityCodeData):
let (offset, length) = (messageEntityCodeData.offset, messageEntityCodeData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Code))
case let .messageEntityPre(offset, length, language):
case let .messageEntityPre(messageEntityPreData):
let (offset, length, language) = (messageEntityPreData.offset, messageEntityPreData.length, messageEntityPreData.language)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Pre(language: language)))
case let .messageEntityTextUrl(offset, length, url):
case let .messageEntityTextUrl(messageEntityTextUrlData):
let (offset, length, url) = (messageEntityTextUrlData.offset, messageEntityTextUrlData.length, messageEntityTextUrlData.url)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .TextUrl(url: url)))
case let .messageEntityMentionName(offset, length, userId):
case let .messageEntityMentionName(messageEntityMentionNameData):
let (offset, length, userId) = (messageEntityMentionNameData.offset, messageEntityMentionNameData.length, messageEntityMentionNameData.userId)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .TextMention(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))))
case let .messageEntityPhone(offset, length):
case let .messageEntityPhone(messageEntityPhoneData):
let (offset, length) = (messageEntityPhoneData.offset, messageEntityPhoneData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .PhoneNumber))
case let .messageEntityCashtag(offset, length):
case let .messageEntityCashtag(messageEntityCashtagData):
let (offset, length) = (messageEntityCashtagData.offset, messageEntityCashtagData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Hashtag))
case let .messageEntityUnderline(offset, length):
case let .messageEntityUnderline(messageEntityUnderlineData):
let (offset, length) = (messageEntityUnderlineData.offset, messageEntityUnderlineData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Underline))
case let .messageEntityStrike(offset, length):
case let .messageEntityStrike(messageEntityStrikeData):
let (offset, length) = (messageEntityStrikeData.offset, messageEntityStrikeData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Strikethrough))
case let .messageEntityBlockquote(flags, offset, length):
case let .messageEntityBlockquote(messageEntityBlockquoteData):
let (flags, offset, length) = (messageEntityBlockquoteData.flags, messageEntityBlockquoteData.offset, messageEntityBlockquoteData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BlockQuote(isCollapsed: (flags & (1 << 0)) != 0)))
case let .messageEntityBankCard(offset, length):
case let .messageEntityBankCard(messageEntityBankCardData):
let (offset, length) = (messageEntityBankCardData.offset, messageEntityBankCardData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BankCard))
case let .messageEntitySpoiler(offset, length):
case let .messageEntitySpoiler(messageEntitySpoilerData):
let (offset, length) = (messageEntitySpoilerData.offset, messageEntitySpoilerData.length)
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Spoiler))
case let .messageEntityCustomEmoji(offset, length, documentId):
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)))
}
}
@@ -712,13 +794,14 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
extension StoreMessage {
convenience init?(apiMessage: Api.Message, accountPeerId: PeerId, peerIsForum: Bool, namespace: MessageId.Namespace = Namespaces.Message.Cloud) {
switch apiMessage {
case let .message(flags, flags2, id, fromId, boosts, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage):
case let .message(messageData):
let (flags, flags2, id, fromId, boosts, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage) = (messageData.flags, messageData.flags2, messageData.id, messageData.fromId, messageData.fromBoostsApplied, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.replyTo, messageData.date, messageData.message, messageData.media, messageData.replyMarkup, messageData.entities, messageData.views, messageData.forwards, messageData.replies, messageData.editDate, messageData.postAuthor, messageData.groupedId, messageData.reactions, messageData.restrictionReason, messageData.ttlPeriod, messageData.quickReplyShortcutId, messageData.effect, messageData.factcheck, messageData.reportDeliveryUntilDate, messageData.paidMessageStars, messageData.suggestedPost, messageData.scheduleRepeatPeriod, messageData.summaryFromLanguage)
var attributes: [MessageAttribute] = []
if (flags2 & (1 << 4)) != 0 {
attributes.append(PendingProcessingMessageAttribute(approximateCompletionTime: date))
}
let resolvedFromId = fromId?.peerId ?? chatPeerId.peerId
var namespace = namespace
@@ -732,10 +815,12 @@ extension StoreMessage {
case .peerUser:
peerId = chatPeerId.peerId
authorId = resolvedFromId
case let .peerChat(chatId):
case let .peerChat(peerChatData):
let chatId = peerChatData.chatId
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))
authorId = resolvedFromId
case let .peerChannel(channelId):
case let .peerChannel(peerChannelData):
let channelId = peerChannelData.channelId
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
authorId = resolvedFromId
}
@@ -744,7 +829,8 @@ extension StoreMessage {
if let replyTo = replyTo {
var threadMessageId: MessageId?
switch replyTo {
case let .messageReplyHeader(innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId):
case let .messageReplyHeader(messageReplyHeaderData):
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
let isForumTopic = (innerFlags & (1 << 3)) != 0
var quote: EngineMessageReplyQuote?
@@ -800,35 +886,37 @@ extension StoreMessage {
if let replyHeader = replyHeader {
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
}
case let .messageReplyStoryHeader(peer, storyId):
case let .messageReplyStoryHeader(messageReplyStoryHeaderData):
let (peer, storyId) = (messageReplyStoryHeaderData.peer, messageReplyStoryHeaderData.storyId)
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: peer.peerId, id: storyId)))
}
}
if threadId == nil && peerId.namespace == Namespaces.Peer.CloudChannel {
threadId = 1
}
var forwardInfo: StoreMessageForwardInfo?
if let fwdFrom = fwdFrom {
switch fwdFrom {
case let .messageFwdHeader(flags, fromId, fromName, date, channelPost, postAuthor, savedFromPeer, savedFromMsgId, savedFromId, savedFromName, savedDate, psaType):
case let .messageFwdHeader(messageFwdHeaderData):
let (flags, fromId, fromName, date, channelPost, postAuthor, savedFromPeer, savedFromMsgId, savedFromId, savedFromName, savedDate, psaType) = (messageFwdHeaderData.flags, messageFwdHeaderData.fromId, messageFwdHeaderData.fromName, messageFwdHeaderData.date, messageFwdHeaderData.channelPost, messageFwdHeaderData.postAuthor, messageFwdHeaderData.savedFromPeer, messageFwdHeaderData.savedFromMsgId, messageFwdHeaderData.savedFromId, messageFwdHeaderData.savedFromName, messageFwdHeaderData.savedDate, messageFwdHeaderData.psaType)
var forwardInfoFlags: MessageForwardInfo.Flags = []
let isImported = (flags & (1 << 7)) != 0
if isImported {
forwardInfoFlags.insert(.isImported)
}
var authorId: PeerId?
var sourceId: PeerId?
var sourceMessageId: MessageId?
if let fromId = fromId {
switch fromId {
case .peerChannel:
let peerId = fromId.peerId
sourceId = peerId
if let channelPost = channelPost {
sourceMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: channelPost)
}
@@ -836,9 +924,9 @@ extension StoreMessage {
authorId = fromId.peerId
}
}
let originalOutgoing = (flags & (1 << 11)) != 0
if let savedFromPeer = savedFromPeer, let savedFromMsgId = savedFromMsgId {
let peerId: PeerId = savedFromPeer.peerId
let messageId: MessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: savedFromMsgId)
@@ -847,7 +935,7 @@ extension StoreMessage {
if savedFromId != nil || savedFromName != nil || savedDate != nil || originalOutgoing {
attributes.append(SourceAuthorInfoMessageAttribute(originalAuthor: savedFromId?.peerId, originalAuthorName: savedFromName, orignalDate: savedDate, originalOutgoing: originalOutgoing))
}
if let authorId = authorId {
forwardInfo = StoreMessageForwardInfo(authorId: authorId, sourceId: sourceId, sourceMessageId: sourceMessageId, date: date, authorSignature: postAuthor, psaType: psaType, flags: forwardInfoFlags)
} else if let sourceId = sourceId {
@@ -1012,7 +1100,8 @@ extension StoreMessage {
if let replies = replies {
let recentRepliersPeerIds: [PeerId]?
switch replies {
case let .messageReplies(_, repliesCount, _, recentRepliers, channelId, maxId, readMaxId):
case let .messageReplies(messageRepliesData):
let (repliesCount, recentRepliers, channelId, maxId, readMaxId) = (messageRepliesData.replies, messageRepliesData.recentRepliers, messageRepliesData.channelId, messageRepliesData.maxId, messageRepliesData.readMaxId)
if let recentRepliers = recentRepliers {
recentRepliersPeerIds = recentRepliers.map { $0.peerId }
} else {
@@ -1035,11 +1124,13 @@ extension StoreMessage {
if let factCheck {
switch factCheck {
case let .factCheck(_, country, text, hash):
case let .factCheck(factCheckData):
let (_, country, text, hash) = (factCheckData.flags, factCheckData.country, factCheckData.text, factCheckData.hash)
let content: FactCheckMessageAttribute.Content
if let text, let country {
switch text {
case let .textWithEntities(text, entities):
case let .textWithEntities(textWithEntitiesData):
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
content = .Loaded(text: text, entities: messageTextEntitiesFromApiEntities(entities), country: country)
}
} else {
@@ -1109,39 +1200,43 @@ extension StoreMessage {
self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), customStableId: nil, globallyUniqueId: nil, groupingKey: groupingId, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: forwardInfo, authorId: authorId, text: messageText, attributes: attributes, media: medias)
case .messageEmpty:
return nil
case let .messageService(flags, id, fromId, chatPeerId, savedPeerId, replyTo, date, action, reactions, ttlPeriod):
case let .messageService(messageServiceData):
let (flags, id, fromId, chatPeerId, savedPeerId, replyTo, date, action, reactions, ttlPeriod) = (messageServiceData.flags, messageServiceData.id, messageServiceData.fromId, messageServiceData.peerId, messageServiceData.savedPeerId, messageServiceData.replyTo, messageServiceData.date, messageServiceData.action, messageServiceData.reactions, messageServiceData.ttlPeriod)
let peerId: PeerId = chatPeerId.peerId
let authorId: PeerId? = fromId?.peerId ?? chatPeerId.peerId
var attributes: [MessageAttribute] = []
var threadId: Int64?
if let savedPeerId {
threadId = savedPeerId.peerId.toInt64()
if chatPeerId.peerId.namespace == Namespaces.Peer.CloudChannel, let replyTo {
switch replyTo {
case let .messageReplyHeader(innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, _, quoteText, quoteEntities, quoteOffset, todoItemId):
case let .messageReplyHeader(messageReplyHeaderData):
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
var quote: EngineMessageReplyQuote?
let isQuote = (innerFlags & (1 << 9)) != 0
if quoteText != nil || replyMedia != nil {
quote = EngineMessageReplyQuote(text: quoteText ?? "", offset: quoteOffset.flatMap(Int.init), entities: messageTextEntitiesFromApiEntities(quoteEntities ?? []), media: textMediaAndExpirationTimerFromApiMedia(replyMedia, peerId).media)
}
if let replyToMsgId = replyToMsgId {
let replyPeerId = replyToPeerId?.peerId ?? peerId
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: nil, quote: quote, isQuote: isQuote, todoItemId: todoItemId))
} else if let replyHeader = replyHeader {
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
}
case let .messageReplyStoryHeader(peer, storyId):
case let .messageReplyStoryHeader(messageReplyStoryHeaderData):
let (peer, storyId) = (messageReplyStoryHeaderData.peer, messageReplyStoryHeaderData.storyId)
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: peer.peerId, id: storyId)))
}
}
} else if let replyTo = replyTo {
var threadMessageId: MessageId?
switch replyTo {
case let .messageReplyHeader(innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId):
case let .messageReplyHeader(messageReplyHeaderData):
let (innerFlags, replyToMsgId, replyToPeerId, replyHeader, replyMedia, replyToTopId, quoteText, quoteEntities, quoteOffset, todoItemId) = (messageReplyHeaderData.flags, messageReplyHeaderData.replyToMsgId, messageReplyHeaderData.replyToPeerId, messageReplyHeaderData.replyFrom, messageReplyHeaderData.replyMedia, messageReplyHeaderData.replyToTopId, messageReplyHeaderData.quoteText, messageReplyHeaderData.quoteEntities, messageReplyHeaderData.quoteOffset, messageReplyHeaderData.todoItemId)
var quote: EngineMessageReplyQuote?
let isQuote = (innerFlags & (1 << 9)) != 0
if quoteText != nil || replyMedia != nil {
@@ -1171,7 +1266,8 @@ extension StoreMessage {
} else if let replyHeader = replyHeader {
attributes.append(QuotedReplyMessageAttribute(apiHeader: replyHeader, quote: quote, isQuote: isQuote))
}
case let .messageReplyStoryHeader(peer, storyId):
case let .messageReplyStoryHeader(messageReplyStoryHeaderData):
let (peer, storyId) = (messageReplyStoryHeaderData.peer, messageReplyStoryHeaderData.storyId)
attributes.append(ReplyStoryAttribute(storyId: StoryId(peerId: peer.peerId, id: storyId)))
}
} else {
@@ -6,7 +6,8 @@ import TelegramApi
extension TelegramChatAdminRights {
init?(apiAdminRights: Api.ChatAdminRights) {
switch apiAdminRights {
case let .chatAdminRights(flags):
case let .chatAdminRights(chatAdminRightsData):
let flags = chatAdminRightsData.flags
if flags == 0 {
return nil
}
@@ -18,6 +19,6 @@ extension TelegramChatAdminRights {
var apiAdminRights: Api.ChatAdminRights {
var filteredFlags = self.rights.rawValue
filteredFlags |= 1 << 12
return .chatAdminRights(flags: filteredFlags)
return .chatAdminRights(Api.ChatAdminRights.Cons_chatAdminRights(flags: filteredFlags))
}
}
@@ -5,7 +5,8 @@ import TelegramApi
extension TelegramChatBannedRights {
init(apiBannedRights: Api.ChatBannedRights) {
switch apiBannedRights {
case let .chatBannedRights(flags, untilDate):
case let .chatBannedRights(chatBannedRightsData):
let (flags, untilDate) = (chatBannedRightsData.flags, chatBannedRightsData.untilDate)
var effectiveFlags = TelegramChatBannedRightsFlags(rawValue: flags)
effectiveFlags.remove(.banSendMedia)
effectiveFlags.remove(TelegramChatBannedRightsFlags(rawValue: 1 << 1))
@@ -18,6 +19,6 @@ extension TelegramChatBannedRights {
effectiveFlags.remove(.banSendMedia)
effectiveFlags.remove(TelegramChatBannedRightsFlags(rawValue: 1 << 1))
return .chatBannedRights(flags: effectiveFlags.rawValue, untilDate: self.untilDate)
return .chatBannedRights(.init(flags: effectiveFlags.rawValue, untilDate: self.untilDate))
}
}
@@ -5,17 +5,20 @@ import TelegramApi
extension TelegramExtendedMedia {
init?(apiExtendedMedia: Api.MessageExtendedMedia, peerId: PeerId) {
switch apiExtendedMedia {
case let .messageExtendedMediaPreview(_, width, height, thumb, videoDuration):
case let .messageExtendedMediaPreview(messageExtendedMediaPreviewData):
let (width, height, thumb, videoDuration) = (messageExtendedMediaPreviewData.w, messageExtendedMediaPreviewData.h, messageExtendedMediaPreviewData.thumb, messageExtendedMediaPreviewData.videoDuration)
var dimensions: PixelDimensions?
if let width = width, let height = height {
dimensions = PixelDimensions(width: width, height: height)
}
var immediateThumbnailData: Data?
if let thumb = thumb, case let .photoStrippedSize(_, bytes) = thumb {
if let thumb = thumb, case let .photoStrippedSize(photoStrippedSizeData) = thumb {
let bytes = photoStrippedSizeData.bytes
immediateThumbnailData = bytes.makeData()
}
self = .preview(dimensions: dimensions, immediateThumbnailData: immediateThumbnailData, videoDuration: videoDuration)
case let .messageExtendedMedia(apiMedia):
case let .messageExtendedMedia(messageExtendedMediaData):
let apiMedia = messageExtendedMediaData.media
if let media = textMediaAndExpirationTimerFromApiMedia(apiMedia, peerId).media {
self = .full(media: media)
} else {
@@ -5,33 +5,44 @@ import TelegramApi
func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMediaAction? {
switch action {
case let .messageActionChannelCreate(title):
case let .messageActionChannelCreate(messageActionChannelCreateData):
let title = messageActionChannelCreateData.title
return TelegramMediaAction(action: .groupCreated(title: title))
case let .messageActionChannelMigrateFrom(title, chatId):
case let .messageActionChannelMigrateFrom(messageActionChannelMigrateFromData):
let (title, chatId) = (messageActionChannelMigrateFromData.title, messageActionChannelMigrateFromData.chatId)
return TelegramMediaAction(action: .channelMigratedFromGroup(title: title, groupId: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))))
case let .messageActionChatAddUser(users):
case let .messageActionChatAddUser(messageActionChatAddUserData):
let users = messageActionChatAddUserData.users
return TelegramMediaAction(action: .addedMembers(peerIds: users.map({ PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) })))
case let .messageActionChatCreate(title, _):
case let .messageActionChatCreate(messageActionChatCreateData):
let title = messageActionChatCreateData.title
return TelegramMediaAction(action: .groupCreated(title: title))
case .messageActionChatDeletePhoto:
return TelegramMediaAction(action: .photoUpdated(image: nil))
case let .messageActionChatDeleteUser(userId):
case let .messageActionChatDeleteUser(messageActionChatDeleteUserData):
let userId = messageActionChatDeleteUserData.userId
return TelegramMediaAction(action: .removedMembers(peerIds: [PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))]))
case let .messageActionChatEditPhoto(photo):
case let .messageActionChatEditPhoto(messageActionChatEditPhotoData):
let photo = messageActionChatEditPhotoData.photo
return TelegramMediaAction(action: .photoUpdated(image: telegramMediaImageFromApiPhoto(photo)))
case let .messageActionChatEditTitle(title):
case let .messageActionChatEditTitle(messageActionChatEditTitleData):
let title = messageActionChatEditTitleData.title
return TelegramMediaAction(action: .titleUpdated(title: title))
case let .messageActionChatJoinedByLink(inviterId):
case let .messageActionChatJoinedByLink(messageActionChatJoinedByLinkData):
let inviterId = messageActionChatJoinedByLinkData.inviterId
return TelegramMediaAction(action: .joinedByLink(inviter: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId))))
case let .messageActionChatMigrateTo(channelId):
case let .messageActionChatMigrateTo(messageActionChatMigrateToData):
let channelId = messageActionChatMigrateToData.channelId
return TelegramMediaAction(action: .groupMigratedToChannel(channelId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))))
case .messageActionHistoryClear:
return TelegramMediaAction(action: .historyCleared)
case .messageActionPinMessage:
return TelegramMediaAction(action: .pinnedMessageUpdated)
case let .messageActionGameScore(gameId, score):
case let .messageActionGameScore(messageActionGameScoreData):
let (gameId, score) = (messageActionGameScoreData.gameId, messageActionGameScoreData.score)
return TelegramMediaAction(action: .gameScore(gameId: gameId, score: score))
case let .messageActionPhoneCall(flags, callId, reason, duration):
case let .messageActionPhoneCall(messageActionPhoneCallData):
let (flags, callId, reason, duration) = (messageActionPhoneCallData.flags, messageActionPhoneCallData.callId, messageActionPhoneCallData.reason, messageActionPhoneCallData.duration)
var discardReason: PhoneCallDiscardReason?
if let reason = reason {
discardReason = PhoneCallDiscardReason(apiReason: reason)
@@ -40,7 +51,8 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return TelegramMediaAction(action: .phoneCall(callId: callId, discardReason: discardReason, duration: duration, isVideo: isVideo))
case .messageActionEmpty:
return nil
case let .messageActionPaymentSent(flags, currency, totalAmount, invoiceSlug, subscriptionUntilDate):
case let .messageActionPaymentSent(messageActionPaymentSentData):
let (flags, currency, totalAmount, invoiceSlug, subscriptionUntilDate) = (messageActionPaymentSentData.flags, messageActionPaymentSentData.currency, messageActionPaymentSentData.totalAmount, messageActionPaymentSentData.invoiceSlug, messageActionPaymentSentData.subscriptionUntilDate)
let _ = subscriptionUntilDate
let isRecurringInit = (flags & (1 << 2)) != 0
let isRecurringUsed = (flags & (1 << 3)) != 0
@@ -49,14 +61,17 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return nil
case .messageActionScreenshotTaken:
return TelegramMediaAction(action: .historyScreenshot)
case let .messageActionCustomAction(message):
case let .messageActionCustomAction(messageActionCustomActionData):
let message = messageActionCustomActionData.message
return TelegramMediaAction(action: .customText(text: message, entities: [], additionalAttributes: nil))
case let .messageActionBotAllowed(flags, domain, app):
case let .messageActionBotAllowed(messageActionBotAllowedData):
let (flags, domain, app) = (messageActionBotAllowedData.flags, messageActionBotAllowedData.domain, messageActionBotAllowedData.app)
if let domain = domain {
return TelegramMediaAction(action: .botDomainAccessGranted(domain: domain))
} else {
var appName: String?
if case let .botApp(_, _, _, _, appNameValue, _, _, _, _) = app {
if case let .botApp(botAppData) = app {
let appNameValue = botAppData.title
appName = appNameValue
}
var type: BotSendMessageAccessGrantedType?
@@ -70,38 +85,48 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
}
case .messageActionSecureValuesSentMe:
return nil
case let .messageActionSecureValuesSent(types):
case let .messageActionSecureValuesSent(messageActionSecureValuesSentData):
let types = messageActionSecureValuesSentData.types
return TelegramMediaAction(action: .botSentSecureValues(types: types.map(SentSecureValueType.init)))
case .messageActionContactSignUp:
return TelegramMediaAction(action: .peerJoined)
case let .messageActionGeoProximityReached(fromId, toId, distance):
case let .messageActionGeoProximityReached(messageActionGeoProximityReachedData):
let (fromId, toId, distance) = (messageActionGeoProximityReachedData.fromId, messageActionGeoProximityReachedData.toId, messageActionGeoProximityReachedData.distance)
return TelegramMediaAction(action: .geoProximityReached(from: fromId.peerId, to: toId.peerId, distance: distance))
case let .messageActionGroupCall(_, call, duration):
case let .messageActionGroupCall(messageActionGroupCallData):
let (call, duration) = (messageActionGroupCallData.call, messageActionGroupCallData.duration)
switch call {
case let .inputGroupCall(id, accessHash):
case let .inputGroupCall(inputGroupCallData):
let (id, accessHash) = (inputGroupCallData.id, inputGroupCallData.accessHash)
return TelegramMediaAction(action: .groupPhoneCall(callId: id, accessHash: accessHash, scheduleDate: nil, duration: duration))
case .inputGroupCallSlug, .inputGroupCallInviteMessage:
return nil
}
case let .messageActionInviteToGroupCall(call, userIds):
case let .messageActionInviteToGroupCall(messageActionInviteToGroupCallData):
let (call, userIds) = (messageActionInviteToGroupCallData.call, messageActionInviteToGroupCallData.users)
switch call {
case let .inputGroupCall(id, accessHash):
case let .inputGroupCall(inputGroupCallData):
let (id, accessHash) = (inputGroupCallData.id, inputGroupCallData.accessHash)
return TelegramMediaAction(action: .inviteToGroupPhoneCall(callId: id, accessHash: accessHash, peerIds: userIds.map { userId in
PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
}))
case .inputGroupCallSlug, .inputGroupCallInviteMessage:
return nil
}
case let .messageActionSetMessagesTTL(_, period, autoSettingFrom):
case let .messageActionSetMessagesTTL(messageActionSetMessagesTTLData):
let (period, autoSettingFrom) = (messageActionSetMessagesTTLData.period, messageActionSetMessagesTTLData.autoSettingFrom)
return TelegramMediaAction(action: .messageAutoremoveTimeoutUpdated(period: period, autoSettingSource: autoSettingFrom.flatMap { PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value($0)) }))
case let .messageActionGroupCallScheduled(call, scheduleDate):
case let .messageActionGroupCallScheduled(messageActionGroupCallScheduledData):
let (call, scheduleDate) = (messageActionGroupCallScheduledData.call, messageActionGroupCallScheduledData.scheduleDate)
switch call {
case let .inputGroupCall(id, accessHash):
case let .inputGroupCall(inputGroupCallData):
let (id, accessHash) = (inputGroupCallData.id, inputGroupCallData.accessHash)
return TelegramMediaAction(action: .groupPhoneCall(callId: id, accessHash: accessHash, scheduleDate: scheduleDate, duration: nil))
case .inputGroupCallSlug, .inputGroupCallInviteMessage:
return nil
}
case let .messageActionSetChatTheme(chatTheme):
case let .messageActionSetChatTheme(messageActionSetChatThemeData):
let chatTheme = messageActionSetChatThemeData.theme
if let chatTheme = ChatTheme(apiChatTheme: chatTheme) {
return TelegramMediaAction(action: .setChatTheme(chatTheme: chatTheme))
} else {
@@ -109,13 +134,19 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
}
case .messageActionChatJoinedByRequest:
return TelegramMediaAction(action: .joinedByRequest)
case let .messageActionWebViewDataSentMe(text, _), let .messageActionWebViewDataSent(text):
case let .messageActionWebViewDataSentMe(messageActionWebViewDataSentMeData):
let text = messageActionWebViewDataSentMeData.text
return TelegramMediaAction(action: .webViewData(text))
case let .messageActionGiftPremium(_, currency, amount, days, cryptoCurrency, cryptoAmount, message):
case let .messageActionWebViewDataSent(messageActionWebViewDataSentData):
let text = messageActionWebViewDataSentData.text
return TelegramMediaAction(action: .webViewData(text))
case let .messageActionGiftPremium(messageActionGiftPremiumData):
let (currency, amount, days, cryptoCurrency, cryptoAmount, message) = (messageActionGiftPremiumData.currency, messageActionGiftPremiumData.amount, messageActionGiftPremiumData.days, messageActionGiftPremiumData.cryptoCurrency, messageActionGiftPremiumData.cryptoAmount, messageActionGiftPremiumData.message)
let text: String?
let entities: [MessageTextEntity]?
switch message {
case let .textWithEntities(textValue, entitiesValue):
case let .textWithEntities(textWithEntitiesData):
let (textValue, entitiesValue) = (textWithEntitiesData.text, textWithEntitiesData.entities)
text = textValue
entities = messageTextEntitiesFromApiEntities(entitiesValue)
default:
@@ -123,11 +154,14 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
entities = nil
}
return TelegramMediaAction(action: .giftPremium(currency: currency, amount: amount, days: days, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, text: text, entities: entities))
case let .messageActionGiftStars(_, currency, amount, stars, cryptoCurrency, cryptoAmount, transactionId):
case let .messageActionGiftStars(messageActionGiftStarsData):
let (currency, amount, stars, cryptoCurrency, cryptoAmount, transactionId) = (messageActionGiftStarsData.currency, messageActionGiftStarsData.amount, messageActionGiftStarsData.stars, messageActionGiftStarsData.cryptoCurrency, messageActionGiftStarsData.cryptoAmount, messageActionGiftStarsData.transactionId)
return TelegramMediaAction(action: .giftStars(currency: currency, amount: amount, count: stars, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, transactionId: transactionId))
case let .messageActionTopicCreate(_, title, iconColor, iconEmojiId):
case let .messageActionTopicCreate(messageActionTopicCreateData):
let (title, iconColor, iconEmojiId) = (messageActionTopicCreateData.title, messageActionTopicCreateData.iconColor, messageActionTopicCreateData.iconEmojiId)
return TelegramMediaAction(action: .topicCreated(title: title, iconColor: iconColor, iconFileId: iconEmojiId))
case let .messageActionTopicEdit(flags, title, iconEmojiId, closed, hidden):
case let .messageActionTopicEdit(messageActionTopicEditData):
let (flags, title, iconEmojiId, closed, hidden) = (messageActionTopicEditData.flags, messageActionTopicEditData.title, messageActionTopicEditData.iconEmojiId, messageActionTopicEditData.closed, messageActionTopicEditData.hidden)
var components: [TelegramMediaActionType.ForumTopicEditComponent] = []
if let title = title {
components.append(.title(title))
@@ -142,50 +176,63 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
components.append(.isHidden(hidden == .boolTrue))
}
return TelegramMediaAction(action: .topicEdited(components: components))
case let .messageActionSuggestProfilePhoto(photo):
case let .messageActionSuggestProfilePhoto(messageActionSuggestProfilePhotoData):
let photo = messageActionSuggestProfilePhotoData.photo
return TelegramMediaAction(action: .suggestedProfilePhoto(image: telegramMediaImageFromApiPhoto(photo)))
case let .messageActionRequestedPeer(buttonId, peers):
case let .messageActionRequestedPeer(messageActionRequestedPeerData):
let (buttonId, peers) = (messageActionRequestedPeerData.buttonId, messageActionRequestedPeerData.peers)
return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerIds: peers.map { $0.peerId }))
case let .messageActionRequestedPeerSentMe(buttonId, _):
case let .messageActionRequestedPeerSentMe(messageActionRequestedPeerSentMeData):
let buttonId = messageActionRequestedPeerSentMeData.buttonId
return TelegramMediaAction(action: .requestedPeer(buttonId: buttonId, peerIds: []))
case let .messageActionSetChatWallPaper(flags, wallpaper):
case let .messageActionSetChatWallPaper(messageActionSetChatWallPaperData):
let (flags, wallpaper) = (messageActionSetChatWallPaperData.flags, messageActionSetChatWallPaperData.wallpaper)
if (flags & (1 << 0)) != 0 {
return TelegramMediaAction(action: .setSameChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper)))
} else {
return TelegramMediaAction(action: .setChatWallpaper(wallpaper: TelegramWallpaper(apiWallpaper: wallpaper), forBoth: (flags & (1 << 1)) != 0))
}
case let .messageActionGiftCode(flags, boostPeer, months, slug, currency, amount, cryptoCurrency, cryptoAmount, message):
case let .messageActionGiftCode(messageActionGiftCodeData):
let (flags, boostPeer, days, slug, currency, amount, cryptoCurrency, cryptoAmount, message) = (messageActionGiftCodeData.flags, messageActionGiftCodeData.boostPeer, messageActionGiftCodeData.days, messageActionGiftCodeData.slug, messageActionGiftCodeData.currency, messageActionGiftCodeData.amount, messageActionGiftCodeData.cryptoCurrency, messageActionGiftCodeData.cryptoAmount, messageActionGiftCodeData.message)
let text: String?
let entities: [MessageTextEntity]?
switch message {
case let .textWithEntities(textValue, entitiesValue):
case let .textWithEntities(textWithEntitiesData):
let (textValue, entitiesValue) = (textWithEntitiesData.text, textWithEntitiesData.entities)
text = textValue
entities = messageTextEntitiesFromApiEntities(entitiesValue)
default:
text = nil
entities = nil
}
return TelegramMediaAction(action: .giftCode(slug: slug, fromGiveaway: (flags & (1 << 0)) != 0, isUnclaimed: (flags & (1 << 5)) != 0, boostPeerId: boostPeer?.peerId, months: months, currency: currency, amount: amount, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, text: text, entities: entities))
case let .messageActionGiveawayLaunch(_, stars):
return TelegramMediaAction(action: .giveawayLaunched(stars: stars))
case let .messageActionGiveawayResults(flags, winners, unclaimed):
return TelegramMediaAction(action: .giftCode(slug: slug, fromGiveaway: (flags & (1 << 0)) != 0, isUnclaimed: (flags & (1 << 5)) != 0, boostPeerId: boostPeer?.peerId, months: days, currency: currency, amount: amount, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, text: text, entities: entities))
case let .messageActionGiveawayLaunch(messageActionGiveawayLaunchData):
return TelegramMediaAction(action: .giveawayLaunched(stars: messageActionGiveawayLaunchData.stars))
case let .messageActionGiveawayResults(messageActionGiveawayResultsData):
let (flags, winners, unclaimed) = (messageActionGiveawayResultsData.flags, messageActionGiveawayResultsData.winnersCount, messageActionGiveawayResultsData.unclaimedCount)
return TelegramMediaAction(action: .giveawayResults(winners: winners, unclaimed: unclaimed, stars: (flags & (1 << 0)) != 0))
case let .messageActionBoostApply(boosts):
case let .messageActionBoostApply(messageActionBoostApplyData):
let boosts = messageActionBoostApplyData.boosts
return TelegramMediaAction(action: .boostsApplied(boosts: boosts))
case let .messageActionPaymentRefunded(_, peer, currency, totalAmount, payload, charge):
case let .messageActionPaymentRefunded(messageActionPaymentRefundedData):
let (peer, currency, totalAmount, payload, charge) = (messageActionPaymentRefundedData.peer, messageActionPaymentRefundedData.currency, messageActionPaymentRefundedData.totalAmount, messageActionPaymentRefundedData.payload, messageActionPaymentRefundedData.charge)
let transactionId: String
switch charge {
case let .paymentCharge(id, _):
case let .paymentCharge(paymentChargeData):
let id = paymentChargeData.id
transactionId = id
}
return TelegramMediaAction(action: .paymentRefunded(peerId: peer.peerId, currency: currency, totalAmount: totalAmount, payload: payload?.makeData(), transactionId: transactionId))
case let .messageActionPrizeStars(flags, stars, transactionId, boostPeer, giveawayMsgId):
case let .messageActionPrizeStars(messageActionPrizeStarsData):
let (flags, stars, transactionId, boostPeer, giveawayMsgId) = (messageActionPrizeStarsData.flags, messageActionPrizeStarsData.stars, messageActionPrizeStarsData.transactionId, messageActionPrizeStarsData.boostPeer, messageActionPrizeStarsData.giveawayMsgId)
return TelegramMediaAction(action: .prizeStars(amount: stars, isUnclaimed: (flags & (1 << 2)) != 0, boostPeerId: boostPeer.peerId, transactionId: transactionId, giveawayMessageId: MessageId(peerId: boostPeer.peerId, namespace: Namespaces.Message.Cloud, id: giveawayMsgId)))
case let .messageActionStarGift(flags, apiGift, message, convertStars, upgradeMessageId, upgradeStars, fromId, peer, savedId, prepaidUpgradeHash, giftMessageId, toId, number):
case let .messageActionStarGift(messageActionStarGiftData):
let (flags, apiGift, message, convertStars, upgradeMessageId, upgradeStars, fromId, peer, savedId, prepaidUpgradeHash, giftMessageId, toId, number) = (messageActionStarGiftData.flags, messageActionStarGiftData.gift, messageActionStarGiftData.message, messageActionStarGiftData.convertStars, messageActionStarGiftData.upgradeMsgId, messageActionStarGiftData.upgradeStars, messageActionStarGiftData.fromId, messageActionStarGiftData.peer, messageActionStarGiftData.savedId, messageActionStarGiftData.prepaidUpgradeHash, messageActionStarGiftData.giftMsgId, messageActionStarGiftData.toId, messageActionStarGiftData.giftNum)
let text: String?
let entities: [MessageTextEntity]?
switch message {
case let .textWithEntities(textValue, entitiesValue):
case let .textWithEntities(textWithEntitiesData):
let (textValue, entitiesValue) = (textWithEntitiesData.text, textWithEntitiesData.entities)
text = textValue
entities = messageTextEntitiesFromApiEntities(entitiesValue)
default:
@@ -196,21 +243,25 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return nil
}
return TelegramMediaAction(action: .starGift(gift: gift, convertStars: convertStars, text: text, entities: entities, nameHidden: (flags & (1 << 0)) != 0, savedToProfile: (flags & (1 << 2)) != 0, converted: (flags & (1 << 3)) != 0, upgraded: (flags & (1 << 5)) != 0, canUpgrade: (flags & (1 << 10)) != 0, upgradeStars: upgradeStars, isRefunded: (flags & (1 << 9)) != 0, isPrepaidUpgrade: (flags & (1 << 13)) != 0, upgradeMessageId: upgradeMessageId, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, prepaidUpgradeHash: prepaidUpgradeHash, giftMessageId: giftMessageId, upgradeSeparate: (flags & (1 << 16)) != 0, isAuctionAcquired: (flags & (1 << 17)) != 0, toPeerId: toId?.peerId, number: number))
case let .messageActionStarGiftUnique(flags, apiGift, canExportAt, transferStars, fromId, peer, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars):
case let .messageActionStarGiftUnique(messageActionStarGiftUniqueData):
let (flags, apiGift, canExportAt, transferStars, fromId, peer, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars, canCraftAt) = (messageActionStarGiftUniqueData.flags, messageActionStarGiftUniqueData.gift, messageActionStarGiftUniqueData.canExportAt, messageActionStarGiftUniqueData.transferStars, messageActionStarGiftUniqueData.fromId, messageActionStarGiftUniqueData.peer, messageActionStarGiftUniqueData.savedId, messageActionStarGiftUniqueData.resaleAmount, messageActionStarGiftUniqueData.canTransferAt, messageActionStarGiftUniqueData.canResellAt, messageActionStarGiftUniqueData.dropOriginalDetailsStars, messageActionStarGiftUniqueData.canCraftAt)
guard let gift = StarGift(apiStarGift: apiGift) else {
return nil
}
return TelegramMediaAction(action: .starGiftUnique(gift: gift, isUpgrade: (flags & (1 << 0)) != 0, isTransferred: (flags & (1 << 1)) != 0, savedToProfile: (flags & (1 << 2)) != 0, canExportDate: canExportAt, transferStars: transferStars, isRefunded: (flags & (1 << 5)) != 0, isPrepaidUpgrade: (flags & (1 << 11)) != 0, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, resaleAmount: resaleAmount.flatMap { CurrencyAmount(apiAmount: $0) }, canTransferDate: canTransferDate, canResaleDate: canResaleDate, dropOriginalDetailsStars: dropOriginalDetailsStars, assigned: (flags & (1 << 13)) != 0, fromOffer: (flags & (1 << 14)) != 0))
case let .messageActionPaidMessagesRefunded(count, stars):
return TelegramMediaAction(action: .starGiftUnique(gift: gift, isUpgrade: (flags & (1 << 0)) != 0, isTransferred: (flags & (1 << 1)) != 0, savedToProfile: (flags & (1 << 2)) != 0, canExportDate: canExportAt, transferStars: transferStars, isRefunded: (flags & (1 << 5)) != 0, isPrepaidUpgrade: (flags & (1 << 11)) != 0, peerId: peer?.peerId, senderId: fromId?.peerId, savedId: savedId, resaleAmount: resaleAmount.flatMap { CurrencyAmount(apiAmount: $0) }, canTransferDate: canTransferDate, canResaleDate: canResaleDate, dropOriginalDetailsStars: dropOriginalDetailsStars, assigned: (flags & (1 << 13)) != 0, fromOffer: (flags & (1 << 14)) != 0, canCraftAt: canCraftAt, isCrafted: (flags & (1 << 16)) != 0))
case let .messageActionPaidMessagesRefunded(messageActionPaidMessagesRefundedData):
let (count, stars) = (messageActionPaidMessagesRefundedData.count, messageActionPaidMessagesRefundedData.stars)
return TelegramMediaAction(action: .paidMessagesRefunded(count: count, stars: stars))
case let .messageActionPaidMessagesPrice(flags, stars):
case let .messageActionPaidMessagesPrice(messageActionPaidMessagesPriceData):
let (flags, stars) = (messageActionPaidMessagesPriceData.flags, messageActionPaidMessagesPriceData.stars)
let broadcastMessagesAllowed = (flags & (1 << 0)) != 0
return TelegramMediaAction(action: .paidMessagesPriceEdited(stars: stars, broadcastMessagesAllowed: broadcastMessagesAllowed))
case let .messageActionConferenceCall(flags, callId, duration, otherParticipants):
case let .messageActionConferenceCall(messageActionConferenceCallData):
let (flags, callId, duration, otherParticipants) = (messageActionConferenceCallData.flags, messageActionConferenceCallData.callId, messageActionConferenceCallData.duration, messageActionConferenceCallData.otherParticipants)
let isMissed = (flags & (1 << 0)) != 0
let isActive = (flags & (1 << 1)) != 0
let isVideo = (flags & (1 << 4)) != 0
var mappedFlags = TelegramMediaActionType.ConferenceCall.Flags()
if isMissed {
mappedFlags.insert(.isMissed)
@@ -221,18 +272,21 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
if isVideo {
mappedFlags.insert(.isVideo)
}
return TelegramMediaAction(action: .conferenceCall(TelegramMediaActionType.ConferenceCall(
callId: callId,
duration: duration,
flags: mappedFlags,
otherParticipants: otherParticipants.flatMap({ return $0.map(\.peerId) }) ?? []
)))
case let .messageActionTodoCompletions(completed, incompleted):
case let .messageActionTodoCompletions(messageActionTodoCompletionsData):
let (completed, incompleted) = (messageActionTodoCompletionsData.completed, messageActionTodoCompletionsData.incompleted)
return TelegramMediaAction(action: .todoCompletions(completed: completed, incompleted: incompleted))
case let .messageActionTodoAppendTasks(list):
case let .messageActionTodoAppendTasks(messageActionTodoAppendTasksData):
let list = messageActionTodoAppendTasksData.list
return TelegramMediaAction(action: .todoAppendTasks(list.map { TelegramMediaTodo.Item(apiItem: $0) }))
case let .messageActionSuggestedPostApproval(flags, rejectComment, scheduleDate, starsAmount):
case let .messageActionSuggestedPostApproval(messageActionSuggestedPostApprovalData):
let (flags, rejectComment, scheduleDate, starsAmount) = (messageActionSuggestedPostApprovalData.flags, messageActionSuggestedPostApprovalData.rejectComment, messageActionSuggestedPostApprovalData.scheduleDate, messageActionSuggestedPostApprovalData.price)
let status: TelegramMediaActionType.SuggestedPostApprovalStatus
if (flags & (1 << 0)) != 0 {
let reason: TelegramMediaActionType.SuggestedPostApprovalStatus.RejectionReason
@@ -241,9 +295,11 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
switch starsAmount {
case .none:
balanceNeeded = CurrencyAmount(amount: .zero, currency: .stars)
case let .starsAmount(amount, nanos):
case let .starsAmount(starsAmountData):
let (amount, nanos) = (starsAmountData.amount, starsAmountData.nanos)
balanceNeeded = CurrencyAmount(amount: StarsAmount(value: amount, nanos: nanos), currency: .stars)
case let .starsTonAmount(amount):
case let .starsTonAmount(starsTonAmountData):
let amount = starsTonAmountData.amount
balanceNeeded = CurrencyAmount(amount: StarsAmount(value: amount, nanos: 0), currency: .ton)
}
reason = .lowBalance(balanceNeeded: balanceNeeded)
@@ -256,9 +312,11 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
switch starsAmount {
case .none:
amountValue = CurrencyAmount(amount: .zero, currency: .stars)
case let .starsAmount(amount, nanos):
case let .starsAmount(starsAmountData):
let (amount, nanos) = (starsAmountData.amount, starsAmountData.nanos)
amountValue = CurrencyAmount(amount: StarsAmount(value: amount, nanos: nanos), currency: .stars)
case let .starsTonAmount(amount):
case let .starsTonAmount(starsTonAmountData):
let amount = starsTonAmountData.amount
amountValue = CurrencyAmount(amount: StarsAmount(value: amount, nanos: 0), currency: .ton)
}
status = .rejected(reason: .lowBalance(balanceNeeded: amountValue), comment: nil)
@@ -266,25 +324,41 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
status = .approved(timestamp: scheduleDate, amount: starsAmount.flatMap(CurrencyAmount.init(apiAmount:)))
}
return TelegramMediaAction(action: .suggestedPostApprovalStatus(status: status))
case let .messageActionGiftTon(_, currency, amount, cryptoCurrency, cryptoAmount, transactionId):
case let .messageActionGiftTon(messageActionGiftTonData):
let (currency, amount, cryptoCurrency, cryptoAmount, transactionId) = (messageActionGiftTonData.currency, messageActionGiftTonData.amount, messageActionGiftTonData.cryptoCurrency, messageActionGiftTonData.cryptoAmount, messageActionGiftTonData.transactionId)
return TelegramMediaAction(action: .giftTon(currency: currency, amount: amount, cryptoCurrency: cryptoCurrency, cryptoAmount: cryptoAmount, transactionId: transactionId))
case let .messageActionSuggestedPostSuccess(price):
case let .messageActionSuggestedPostSuccess(messageActionSuggestedPostSuccessData):
let price = messageActionSuggestedPostSuccessData.price
return TelegramMediaAction(action: .suggestedPostSuccess(amount: CurrencyAmount(apiAmount: price)))
case let .messageActionSuggestedPostRefund(flags):
case let .messageActionSuggestedPostRefund(messageActionSuggestedPostRefundData):
let flags = messageActionSuggestedPostRefundData.flags
return TelegramMediaAction(action: .suggestedPostRefund(TelegramMediaActionType.SuggestedPostRefund(isUserInitiated: (flags & (1 << 0)) != 0)))
case let .messageActionSuggestBirthday(birthday):
case let .messageActionSuggestBirthday(messageActionSuggestBirthdayData):
let birthday = messageActionSuggestBirthdayData.birthday
return TelegramMediaAction(action: .suggestedBirthday(TelegramBirthday(apiBirthday: birthday)))
case let .messageActionStarGiftPurchaseOffer(flags, apiGift, price, expiresAt):
case let .messageActionStarGiftPurchaseOffer(messageActionStarGiftPurchaseOfferData):
let (flags, apiGift, price, expiresAt) = (messageActionStarGiftPurchaseOfferData.flags, messageActionStarGiftPurchaseOfferData.gift, messageActionStarGiftPurchaseOfferData.price, messageActionStarGiftPurchaseOfferData.expiresAt)
guard let gift = StarGift(apiStarGift: apiGift) else {
return nil
}
return TelegramMediaAction(action: .starGiftPurchaseOffer(gift: gift, amount: CurrencyAmount(apiAmount: price), expireDate: expiresAt, isAccepted: (flags & (1 << 0)) != 0, isDeclined: (flags & (1 << 1)) != 0))
case let .messageActionStarGiftPurchaseOfferDeclined(flags, apiGift, price):
case let .messageActionStarGiftPurchaseOfferDeclined(messageActionStarGiftPurchaseOfferDeclinedData):
let (flags, apiGift, price) = (messageActionStarGiftPurchaseOfferDeclinedData.flags, messageActionStarGiftPurchaseOfferDeclinedData.gift, messageActionStarGiftPurchaseOfferDeclinedData.price)
guard let gift = StarGift(apiStarGift: apiGift) else {
return nil
}
return TelegramMediaAction(action: .starGiftPurchaseOfferDeclined(gift: gift, amount: CurrencyAmount(apiAmount: price), hasExpired: (flags & (1 << 0)) != 0))
case let .messageActionNewCreatorPending(messageActionNewCreatorPending):
return TelegramMediaAction(action: .groupCreatorChange(TelegramMediaActionType.GroupCreatorChange(
kind: .pending,
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionNewCreatorPending.newCreatorId))
)))
case let .messageActionChangeCreator(messageActionChangeCreator):
return TelegramMediaAction(action: .groupCreatorChange(TelegramMediaActionType.GroupCreatorChange(
kind: .applied,
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionChangeCreator.newCreatorId))
)))
}
}
@@ -69,13 +69,16 @@ extension StickerPackReference {
switch apiInputSet {
case .inputStickerSetEmpty:
return nil
case let .inputStickerSetID(id, accessHash):
case let .inputStickerSetID(inputStickerSetIDData):
let (id, accessHash) = (inputStickerSetIDData.id, inputStickerSetIDData.accessHash)
self = .id(id: id, accessHash: accessHash)
case let .inputStickerSetShortName(shortName):
case let .inputStickerSetShortName(inputStickerSetShortNameData):
let shortName = inputStickerSetShortNameData.shortName
self = .name(shortName)
case .inputStickerSetAnimatedEmoji:
self = .animatedEmoji
case let .inputStickerSetDice(emoticon):
case let .inputStickerSetDice(inputStickerSetDiceData):
let emoticon = inputStickerSetDiceData.emoticon
self = .dice(emoticon)
case .inputStickerSetAnimatedEmojiAnimations:
self = .animatedEmojiAnimations
@@ -98,7 +101,8 @@ extension StickerPackReference {
extension StickerMaskCoords {
init(apiMaskCoords: Api.MaskCoords) {
switch apiMaskCoords {
case let .maskCoords(n, x, y, zoom):
case let .maskCoords(maskCoordsData):
let (n, x, y, zoom) = (maskCoordsData.n, maskCoordsData.x, maskCoordsData.y, maskCoordsData.zoom)
self.init(n: n, x: x, y: y, zoom: zoom)
}
}
@@ -108,17 +112,21 @@ func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAtt
var result: [TelegramMediaFileAttribute] = []
for attribute in attributes {
switch attribute {
case let .documentAttributeFilename(fileName):
case let .documentAttributeFilename(documentAttributeFilenameData):
let fileName = documentAttributeFilenameData.fileName
result.append(.FileName(fileName: fileName))
case let .documentAttributeSticker(_, alt, stickerSet, maskCoords):
case let .documentAttributeSticker(documentAttributeStickerData):
let (alt, stickerSet, maskCoords) = (documentAttributeStickerData.alt, documentAttributeStickerData.stickerset, documentAttributeStickerData.maskCoords)
result.append(.Sticker(displayText: alt, packReference: StickerPackReference(apiInputSet: stickerSet), maskData: maskCoords.flatMap(StickerMaskCoords.init)))
case .documentAttributeHasStickers:
result.append(.HasLinkedStickers)
case let .documentAttributeImageSize(w, h):
case let .documentAttributeImageSize(documentAttributeImageSizeData):
let (w, h) = (documentAttributeImageSizeData.w, documentAttributeImageSizeData.h)
result.append(.ImageSize(size: PixelDimensions(width: w, height: h)))
case .documentAttributeAnimated:
result.append(.Animated)
case let .documentAttributeVideo(flags, duration, w, h, preloadSize, videoStart, videoCodec):
case let .documentAttributeVideo(documentAttributeVideoData):
let (flags, duration, w, h, preloadSize, videoStart, videoCodec) = (documentAttributeVideoData.flags, documentAttributeVideoData.duration, documentAttributeVideoData.w, documentAttributeVideoData.h, documentAttributeVideoData.preloadPrefixSize, documentAttributeVideoData.videoStartTs, documentAttributeVideoData.videoCodec)
var videoFlags = TelegramMediaVideoFlags()
if (flags & (1 << 0)) != 0 {
videoFlags.insert(.instantRoundVideo)
@@ -130,11 +138,13 @@ func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAtt
videoFlags.insert(.isSilent)
}
result.append(.Video(duration: Double(duration), size: PixelDimensions(width: w, height: h), flags: videoFlags, preloadSize: preloadSize, coverTime: videoStart, videoCodec: videoCodec))
case let .documentAttributeAudio(flags, duration, title, performer, waveform):
case let .documentAttributeAudio(documentAttributeAudioData):
let (flags, duration, title, performer, waveform) = (documentAttributeAudioData.flags, documentAttributeAudioData.duration, documentAttributeAudioData.title, documentAttributeAudioData.performer, documentAttributeAudioData.waveform)
let isVoice = (flags & (1 << 10)) != 0
let waveformBuffer: Data? = waveform?.makeData()
result.append(.Audio(isVoice: isVoice, duration: Int(duration), title: title, performer: performer, waveform: waveformBuffer))
case let .documentAttributeCustomEmoji(flags, alt, stickerSet):
case let .documentAttributeCustomEmoji(documentAttributeCustomEmojiData):
let (flags, alt, stickerSet) = (documentAttributeCustomEmojiData.flags, documentAttributeCustomEmojiData.alt, documentAttributeCustomEmojiData.stickerset)
let isFree = (flags & (1 << 0)) != 0
let isSingleColor = (flags & (1 << 1)) != 0
result.append(.CustomEmoji(isPremium: !isFree, isSingleColor: isSingleColor, alt: alt, packReference: StickerPackReference(apiInputSet: stickerSet)))
@@ -157,18 +167,23 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
var representations: [TelegramMediaImageRepresentation] = []
for size in sizes {
switch size {
case let .photoCachedSize(type, w, h, _):
case let .photoCachedSize(photoCachedSizeData):
let (type, w, h, _) = (photoCachedSizeData.type, photoCachedSizeData.w, photoCachedSizeData.h, photoCachedSizeData.bytes)
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
case let .photoSize(type, w, h, _):
case let .photoSize(photoSizeData):
let (type, w, h, _) = (photoSizeData.type, photoSizeData.w, photoSizeData.h, photoSizeData.size)
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
case let .photoSizeProgressive(type, w, h, sizes):
case let .photoSizeProgressive(photoSizeProgressiveData):
let (type, w, h, sizes) = (photoSizeProgressiveData.type, photoSizeProgressiveData.w, photoSizeProgressiveData.h, photoSizeProgressiveData.sizes)
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
case let .photoPathSize(_, data):
case let .photoPathSize(photoPathSizeData):
let (_, data) = (photoPathSizeData.type, photoPathSizeData.bytes)
immediateThumbnailData = data.makeData()
case let .photoStrippedSize(_, data):
case let .photoStrippedSize(photoStrippedSizeData):
let (_, data) = (photoStrippedSizeData.type, photoStrippedSizeData.bytes)
immediateThumbnailData = data.makeData()
case .photoSizeEmpty:
break
@@ -179,7 +194,8 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil) -> TelegramMediaFile? {
switch document {
case let .document(_, id, accessHash, fileReference, _, mimeType, size, thumbs, videoThumbs, dcId, attributes):
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 isSticker = false
var isAnimated = false
@@ -203,7 +219,8 @@ func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [A
if let videoThumbs = videoThumbs {
for thumb in videoThumbs {
switch thumb {
case let .videoSize(_, type, w, h, _, _):
case let .videoSize(videoSizeData):
let (_, type, w, h, _, _) = (videoSizeData.flags, videoSizeData.type, videoSizeData.w, videoSizeData.h, videoSizeData.size, videoSizeData.videoStartTs)
let resource: TelegramMediaResource
resource = CloudDocumentSizeMediaResource(datacenterId: dcId, documentId: id, accessHash: accessHash, sizeSpec: type, fileReference: fileReference.makeData())
@@ -6,7 +6,8 @@ import TelegramApi
extension TelegramMediaGame {
convenience init(apiGame: Api.Game) {
switch apiGame {
case let .game(_, id, accessHash, shortName, title, description, photo, document):
case let .game(gameData):
let (id, accessHash, shortName, title, description, photo, document) = (gameData.id, gameData.accessHash, gameData.shortName, gameData.title, gameData.description, gameData.photo, gameData.document)
var file: TelegramMediaFile?
if let document = document {
file = telegramMediaFileFromApiDocument(document, altDocuments: [])
@@ -8,18 +8,22 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
var representations: [TelegramMediaImageRepresentation] = []
for size in sizes {
switch size {
case let .photoCachedSize(type, w, h, _):
case let .photoCachedSize(photoCachedSizeData):
let (type, w, h) = (photoCachedSizeData.type, photoCachedSizeData.w, photoCachedSizeData.h)
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: nil, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
case let .photoSize(type, w, h, size):
case let .photoSize(photoSizeData):
let (type, w, h, size) = (photoSizeData.type, photoSizeData.w, photoSizeData.h, photoSizeData.size)
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
case let .photoSizeProgressive(type, w, h, sizes):
case let .photoSizeProgressive(photoSizeProgressiveData):
let (type, w, h, sizes) = (photoSizeProgressiveData.type, photoSizeProgressiveData.w, photoSizeProgressiveData.h, photoSizeProgressiveData.sizes)
if !sizes.isEmpty {
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(sizes[sizes.count - 1]), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
}
case let .photoStrippedSize(_, data):
case let .photoStrippedSize(photoStrippedSizeData):
let data = photoStrippedSizeData.bytes
immediateThumbnailData = data.makeData()
case .photoPathSize:
break
@@ -32,7 +36,8 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
switch photo {
case let .photo(flags, id, accessHash, fileReference, _, sizes, videoSizes, dcId):
case let .photo(photoData):
let (flags, id, accessHash, fileReference, sizes, videoSizes, dcId) = (photoData.flags, photoData.id, photoData.accessHash, photoData.fileReference, photoData.sizes, photoData.videoSizes, photoData.dcId)
let (immediateThumbnailData, representations) = telegramMediaImageRepresentationsFromApiSizes(datacenterId: dcId, photoId: id, accessHash: accessHash, fileReference: fileReference.makeData(), sizes: sizes)
var imageFlags: TelegramMediaImageFlags = []
let hasStickers = (flags & (1 << 0)) != 0
@@ -45,14 +50,17 @@ func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
if let videoSizes = videoSizes {
for size in videoSizes {
switch size {
case let .videoSize(_, type, w, h, size, videoStartTs):
case let .videoSize(videoSizeData):
let (_, type, w, h, size, videoStartTs) = (videoSizeData.flags, videoSizeData.type, videoSizeData.w, videoSizeData.h, videoSizeData.size, videoSizeData.videoStartTs)
let resource: TelegramMediaResource
resource = CloudPhotoSizeMediaResource(datacenterId: dcId, photoId: id, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference.makeData())
videoRepresentations.append(TelegramMediaImage.VideoRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, startTimestamp: videoStartTs))
case let .videoSizeEmojiMarkup(fileId, backgroundColors):
case let .videoSizeEmojiMarkup(videoSizeEmojiMarkupData):
let (fileId, backgroundColors) = (videoSizeEmojiMarkupData.emojiId, videoSizeEmojiMarkupData.backgroundColors)
emojiMarkup = TelegramMediaImage.EmojiMarkup(content: .emoji(fileId: fileId), backgroundColors: backgroundColors)
case let .videoSizeStickerMarkup(stickerSet, fileId, backgroundColors):
case let .videoSizeStickerMarkup(videoSizeStickerMarkupData):
let (stickerSet, fileId, backgroundColors) = (videoSizeStickerMarkupData.stickerset, videoSizeStickerMarkupData.stickerId, videoSizeStickerMarkupData.backgroundColors)
if let packReference = StickerPackReference(apiInputSet: stickerSet) {
emojiMarkup = TelegramMediaImage.EmojiMarkup(content: .sticker(packReference: packReference, fileId: fileId), backgroundColors: backgroundColors)
}
@@ -9,7 +9,8 @@ func telegramMediaMapFromApiGeoPoint(_ geo: Api.GeoPoint, title: String?, addres
venue = MapVenue(title: title, address: address, provider: provider, id: venueId, type: venueType)
}
switch geo {
case let .geoPoint(_, long, lat, _, accuracyRadius):
case let .geoPoint(geoPointData):
let (_, long, lat, _, accuracyRadius) = (geoPointData.flags, geoPointData.long, geoPointData.lat, geoPointData.accessHash, geoPointData.accuracyRadius)
return TelegramMediaMap(latitude: lat, longitude: long, heading: heading, accuracyRadius: accuracyRadius.flatMap { Double($0) }, venue: venue, liveBroadcastingTimeout: liveBroadcastingTimeout, liveProximityNotificationRadius: liveProximityNotificationRadius)
case .geoPointEmpty:
return TelegramMediaMap(latitude: 0.0, longitude: 0.0, heading: nil, accuracyRadius: nil, venue: venue, liveBroadcastingTimeout: liveBroadcastingTimeout, liveProximityNotificationRadius: liveProximityNotificationRadius)
@@ -19,7 +20,8 @@ func telegramMediaMapFromApiGeoPoint(_ geo: Api.GeoPoint, title: String?, addres
func mapGeoAddressFromApiGeoPointAddress(_ geo: Api.GeoPointAddress) -> MapGeoAddress {
switch geo {
case let .geoPointAddress(_, countryIso2, state, city, street):
case let .geoPointAddress(geoPointAddressData):
let (countryIso2, state, city, street) = (geoPointAddressData.countryIso2, geoPointAddressData.state, geoPointAddressData.city, geoPointAddressData.street)
return MapGeoAddress(country: countryIso2, state: state, city: city, street: street)
}
}
@@ -6,11 +6,13 @@ import TelegramApi
extension TelegramMediaPollOption {
init(apiOption: Api.PollAnswer) {
switch apiOption {
case let .pollAnswer(text, option):
case let .pollAnswer(pollAnswerData):
let (text, option) = (pollAnswerData.text, pollAnswerData.option)
let answerText: String
let answerEntities: [MessageTextEntity]
switch text {
case let .textWithEntities(text, entities):
case let .textWithEntities(textWithEntitiesData):
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
answerText = text
answerEntities = messageTextEntitiesFromApiEntities(entities)
}
@@ -20,14 +22,15 @@ extension TelegramMediaPollOption {
}
var apiOption: Api.PollAnswer {
return .pollAnswer(text: .textWithEntities(text: self.text, entities: apiEntitiesFromMessageTextEntities(self.entities, associatedPeers: SimpleDictionary())), option: Buffer(data: self.opaqueIdentifier))
return .pollAnswer(.init(text: .textWithEntities(.init(text: self.text, entities: apiEntitiesFromMessageTextEntities(self.entities, associatedPeers: SimpleDictionary()))), option: Buffer(data: self.opaqueIdentifier)))
}
}
extension TelegramMediaPollOptionVoters {
init(apiVoters: Api.PollAnswerVoters) {
switch apiVoters {
case let .pollAnswerVoters(flags, option, voters):
case let .pollAnswerVoters(pollAnswerVotersData):
let (flags, option, voters) = (pollAnswerVotersData.flags, pollAnswerVotersData.option, pollAnswerVotersData.voters)
self.init(selected: (flags & (1 << 0)) != 0, opaqueIdentifier: option.makeData(), count: voters, isCorrect: (flags & (1 << 1)) != 0)
}
}
@@ -36,7 +39,8 @@ extension TelegramMediaPollOptionVoters {
extension TelegramMediaPollResults {
init(apiResults: Api.PollResults) {
switch apiResults {
case let .pollResults(_, results, totalVoters, recentVoters, solution, solutionEntities):
case let .pollResults(pollResultsData):
let (results, totalVoters, recentVoters, solution, solutionEntities) = (pollResultsData.results, pollResultsData.totalVoters, pollResultsData.recentVoters, pollResultsData.solution, pollResultsData.solutionEntities)
var parsedSolution: TelegramMediaPollResults.Solution?
if let solution = solution, let solutionEntities = solutionEntities, !solution.isEmpty {
parsedSolution = TelegramMediaPollResults.Solution(text: solution, entities: messageTextEntitiesFromApiEntities(solutionEntities))
@@ -6,11 +6,13 @@ import TelegramApi
extension TelegramMediaTodo.Item {
init(apiItem: Api.TodoItem) {
switch apiItem {
case let .todoItem(id, title):
case let .todoItem(todoItemData):
let (id, title) = (todoItemData.id, todoItemData.title)
let itemText: String
let itemEntities: [MessageTextEntity]
switch title {
case let .textWithEntities(text, entities):
case let .textWithEntities(textWithEntitiesData):
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
itemText = text
itemEntities = messageTextEntitiesFromApiEntities(entities)
}
@@ -19,14 +21,15 @@ extension TelegramMediaTodo.Item {
}
var apiItem: Api.TodoItem {
return .todoItem(id: self.id, title: .textWithEntities(text: self.text, entities: apiEntitiesFromMessageTextEntities(self.entities, associatedPeers: SimpleDictionary())))
return .todoItem(.init(id: self.id, title: .textWithEntities(.init(text: self.text, entities: apiEntitiesFromMessageTextEntities(self.entities, associatedPeers: SimpleDictionary())))))
}
}
extension TelegramMediaTodo.Completion {
init(apiCompletion: Api.TodoCompletion) {
switch apiCompletion {
case let .todoCompletion(id, completedBy, date):
case let .todoCompletion(todoCompletionData):
let (id, completedBy, date) = (todoCompletionData.id, todoCompletionData.completedBy, todoCompletionData.date)
self.init(id: id, date: date, completedBy: completedBy.peerId)
}
}
@@ -6,9 +6,11 @@ import TelegramApi
extension TelegramMediaWebFile {
convenience init(_ document: Api.WebDocument) {
switch document {
case let .webDocument(url, accessHash, size, mimeType, attributes):
case let .webDocument(webDocumentData):
let (url, accessHash, size, mimeType, attributes) = (webDocumentData.url, webDocumentData.accessHash, webDocumentData.size, webDocumentData.mimeType, webDocumentData.attributes)
self.init(resource: WebFileReferenceMediaResource(url: url, size: Int64(size), accessHash: accessHash), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
case let .webDocumentNoProxy(url, size, mimeType, attributes):
case let .webDocumentNoProxy(webDocumentNoProxyData):
let (url, size, mimeType, attributes) = (webDocumentNoProxyData.url, webDocumentNoProxyData.size, webDocumentNoProxyData.mimeType, webDocumentNoProxyData.attributes)
self.init(resource: HttpReferenceMediaResource(url: url, size: Int64(size)), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
}
}
@@ -6,13 +6,15 @@ import TelegramApi
func telegramMediaWebpageAttributeFromApiWebpageAttribute(_ attribute: Api.WebPageAttribute) -> TelegramMediaWebpageAttribute? {
switch attribute {
case let .webPageAttributeTheme(_, documents, settings):
case let .webPageAttributeTheme(webPageAttributeThemeData):
let (_, documents, settings) = (webPageAttributeThemeData.flags, webPageAttributeThemeData.documents, webPageAttributeThemeData.settings)
var files: [TelegramMediaFile] = []
if let documents = documents {
files = documents.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
}
return .theme(TelegraMediaWebpageThemeAttribute(files: files, settings: settings.flatMap { TelegramThemeSettings(apiThemeSettings: $0) }))
case let .webPageAttributeStickerSet(apiFlags, stickers):
case let .webPageAttributeStickerSet(webPageAttributeStickerSetData):
let (apiFlags, stickers) = (webPageAttributeStickerSetData.flags, webPageAttributeStickerSetData.stickers)
var flags = TelegramMediaWebpageStickerPackAttribute.Flags()
if (apiFlags & (1 << 0)) != 0 {
flags.insert(.isEmoji)
@@ -23,16 +25,19 @@ func telegramMediaWebpageAttributeFromApiWebpageAttribute(_ attribute: Api.WebPa
var files: [TelegramMediaFile] = []
files = stickers.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
return .stickerPack(TelegramMediaWebpageStickerPackAttribute(flags: flags, files: files))
case let .webPageAttributeUniqueStarGift(gift):
case let .webPageAttributeUniqueStarGift(webPageAttributeUniqueStarGiftData):
let gift = webPageAttributeUniqueStarGiftData.gift
if let starGift = StarGift(apiStarGift: gift) {
return .starGift(TelegramMediaWebpageStarGiftAttribute(gift: starGift))
}
return nil
case let .webPageAttributeStarGiftCollection(icons):
case let .webPageAttributeStarGiftCollection(webPageAttributeStarGiftCollectionData):
let icons = webPageAttributeStarGiftCollectionData.icons
var files: [TelegramMediaFile] = []
files = icons.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
return .giftCollection(TelegramMediaWebpageGiftCollectionAttribute(files: files))
case let .webPageAttributeStarGiftAuction(apiGift, endDate):
case let .webPageAttributeStarGiftAuction(webPageAttributeStarGiftAuctionData):
let (apiGift, endDate) = (webPageAttributeStarGiftAuctionData.gift, webPageAttributeStarGiftAuctionData.endDate)
guard let gift = StarGift(apiStarGift: apiGift) else {
return nil
}
@@ -46,10 +51,12 @@ func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMedia
switch webpage {
case .webPageNotModified:
return nil
case let .webPagePending(flags, id, url, date):
case let .webPagePending(webPagePendingData):
let (flags, id, url, date) = (webPagePendingData.flags, webPagePendingData.id, webPagePendingData.url, webPagePendingData.date)
let _ = flags
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Pending(date, url))
case let .webPage(flags, id, url, displayUrl, hash, type, siteName, title, description, photo, embedUrl, embedType, embedWidth, embedHeight, duration, author, document, cachedPage, attributes):
case let .webPage(webPageData):
let (flags, id, url, displayUrl, hash, type, siteName, title, description, photo, embedUrl, embedType, embedWidth, embedHeight, duration, author, document, cachedPage, attributes) = (webPageData.flags, webPageData.id, webPageData.url, webPageData.displayUrl, webPageData.hash, webPageData.type, webPageData.siteName, webPageData.title, webPageData.description, webPageData.photo, webPageData.embedUrl, webPageData.embedType, webPageData.embedWidth, webPageData.embedHeight, webPageData.duration, webPageData.author, webPageData.document, webPageData.cachedPage, webPageData.attributes)
var embedSize: PixelDimensions?
if let embedWidth = embedWidth, let embedHeight = embedHeight {
embedSize = PixelDimensions(width: embedWidth, height: embedHeight)
@@ -71,20 +78,21 @@ func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMedia
if let attributes = attributes {
webpageAttributes = attributes.compactMap(telegramMediaWebpageAttributeFromApiWebpageAttribute)
for attribute in attributes {
if case let .webPageAttributeStory(_, peerId, id, _) = attribute {
if case let .webPageAttributeStory(webPageAttributeStoryData) = attribute {
let (_, peerId, id, _) = (webPageAttributeStoryData.flags, webPageAttributeStoryData.peer, webPageAttributeStoryData.id, webPageAttributeStoryData.story)
story = TelegramMediaStory(storyId: StoryId(peerId: peerId.peerId, id: id), isMention: false)
}
}
}
var instantPage: InstantPage?
if let cachedPage = cachedPage {
instantPage = InstantPage(apiPage: cachedPage)
}
let isMediaLargeByDefault = (flags & (1 << 13)) != 0
let imageIsVideoCover = (flags & (1 << 14)) != 0
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Loaded(TelegramMediaWebpageLoadedContent(url: url, displayUrl: displayUrl, hash: hash, type: type, websiteName: siteName, title: title, text: description, embedUrl: embedUrl, embedType: embedType, embedSize: embedSize, duration: webpageDuration, author: author, isMediaLargeByDefault: isMediaLargeByDefault, imageIsVideoCover: imageIsVideoCover, image: image, file: file, story: story, attributes: webpageAttributes, instantPage: instantPage)))
case .webPageEmpty:
return nil
@@ -6,7 +6,8 @@ import TelegramApi
extension TelegramPeerNotificationSettings {
convenience init(apiSettings: Api.PeerNotifySettings) {
switch apiSettings {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
case let .peerNotifySettings(peerNotifySettingsData):
let (showPreviews, muteUntil, iosSound, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, storiesDesktopSound) = (peerNotifySettingsData.showPreviews, peerNotifySettingsData.muteUntil, peerNotifySettingsData.iosSound, peerNotifySettingsData.otherSound, peerNotifySettingsData.storiesMuted, peerNotifySettingsData.storiesHideSender, peerNotifySettingsData.storiesIosSound, peerNotifySettingsData.storiesOtherSound)
let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS)
@@ -68,7 +69,8 @@ extension PeerMessageSound {
self = .default
case .notificationSoundNone:
self = .none
case let .notificationSoundLocal(_, data):
case let .notificationSoundLocal(notificationSoundLocalData):
let (_, data) = (notificationSoundLocalData.title, notificationSoundLocalData.data)
var rawApiSound = data
if let index = rawApiSound.firstIndex(of: ".") {
rawApiSound = String(rawApiSound[..<index])
@@ -94,7 +96,8 @@ extension PeerMessageSound {
}
}
self = parsedSound
case let .notificationSoundRingtone(id):
case let .notificationSoundRingtone(notificationSoundRingtoneData):
let id = notificationSoundRingtoneData.id
self = .cloud(fileId: id)
}
}
@@ -107,12 +110,12 @@ extension PeerMessageSound {
return .notificationSoundDefault
case let .bundledModern(id):
let string = "\(id + 100)"
return .notificationSoundLocal(title: string, data: string)
return .notificationSoundLocal(.init(title: string, data: string))
case let .bundledClassic(id):
let string = "\(id + 2)"
return .notificationSoundLocal(title: string, data: string)
return .notificationSoundLocal(.init(title: string, data: string))
case let .cloud(fileId):
return .notificationSoundRingtone(id: fileId)
return .notificationSoundRingtone(.init(id: fileId))
}
}
}
@@ -5,7 +5,8 @@ import TelegramApi
func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMediaImageRepresentation] {
var representations: [TelegramMediaImageRepresentation] = []
switch photo {
case let .userProfilePhoto(flags, id, strippedThumb, dcId):
case let .userProfilePhoto(userProfilePhotoData):
let (flags, id, strippedThumb, dcId) = (userProfilePhotoData.flags, userProfilePhotoData.photoId, userProfilePhotoData.strippedThumb, userProfilePhotoData.dcId)
let hasVideo = (flags & (1 << 0)) != 0
let isPersonal = (flags & (1 << 2)) != 0
@@ -26,7 +27,8 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia
extension TelegramPeerUsername {
init(apiUsername: Api.Username) {
switch apiUsername {
case let .username(flags, username):
case let .username(usernameData):
let (flags, username) = (usernameData.flags, usernameData.username)
self.init(flags: Flags(rawValue: flags), username: username)
}
}
@@ -35,10 +37,11 @@ extension TelegramPeerUsername {
extension PeerVerification {
init(apiBotVerification: Api.BotVerification) {
switch apiBotVerification {
case let .botVerification(botId, iconFileId, description):
case let .botVerification(botVerificationData):
let (botId, icon, description) = (botVerificationData.botId, botVerificationData.icon, botVerificationData.description)
self.init(
botId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)),
iconFileId: iconFileId,
iconFileId: icon,
description: description
)
}
@@ -49,7 +52,8 @@ extension PeerVerification {
extension TelegramUser {
convenience init(user: Api.User) {
switch user {
case let .user(flags, flags2, id, accessHash, firstName, lastName, username, phone, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, usernames, _, color, profileColor, subscriberCount, verificationIconFileId, _):
case let .user(userData):
let (flags, flags2, id, accessHash, firstName, lastName, username, phone, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, usernames, _, color, profileColor, subscriberCount, verificationIconFileId, _) = (userData.flags, userData.flags2, userData.id, userData.accessHash, userData.firstName, userData.lastName, userData.username, userData.phone, userData.photo, userData.status, userData.botInfoVersion, userData.restrictionReason, userData.botInlinePlaceholder, userData.langCode, userData.emojiStatus, userData.usernames, userData.storiesMaxId, userData.color, userData.profileColor, userData.botActiveUsers, userData.botVerificationIcon, userData.sendPaidMessagesStars)
let representations: [TelegramMediaImageRepresentation] = photo.flatMap(parsedTelegramProfilePhoto) ?? []
let isMin = (flags & (1 << 20)) != 0
@@ -121,6 +125,9 @@ extension TelegramUser {
if (flags2 & (1 << 16)) != 0 {
botFlags.insert(.hasForum)
}
if (flags2 & (1 << 17)) != 0 {
botFlags.insert(.forumManagedByUser)
}
botInfo = BotUserInfo(flags: botFlags, inlinePlaceholder: botInlinePlaceholder)
}
@@ -130,12 +137,14 @@ extension TelegramUser {
var backgroundEmojiId: Int64?
if let color = color {
switch color {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
if let color {
nameColor = .preset(PeerNameColor(rawValue: color))
}
backgroundEmojiId = backgroundEmojiIdValue
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiIdValue, accentColor, colors, darkAccentColor, darkColors):
case let .peerColorCollectible(peerColorCollectibleData):
let (_, collectibleId, giftEmojiId, backgroundEmojiIdValue, accentColor, colors, darkAccentColor, darkColors) = (peerColorCollectibleData.flags, peerColorCollectibleData.collectibleId, peerColorCollectibleData.giftEmojiId, peerColorCollectibleData.backgroundEmojiId, peerColorCollectibleData.accentColor, peerColorCollectibleData.colors, peerColorCollectibleData.darkAccentColor, peerColorCollectibleData.darkColors)
nameColor = .collectible(PeerCollectibleColor(
collectibleId: collectibleId,
giftEmojiFileId: giftEmojiId,
@@ -150,12 +159,13 @@ extension TelegramUser {
break
}
}
var profileColorIndex: Int32?
var profileBackgroundEmojiId: Int64?
if let profileColor = profileColor {
switch profileColor {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
profileColorIndex = color
profileBackgroundEmojiId = backgroundEmojiIdValue
default:
@@ -164,14 +174,16 @@ extension TelegramUser {
}
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, firstName: firstName, lastName: lastName, username: username, phone: phone, photo: representations, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? [], storiesHidden: storiesHidden, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: profileColorIndex.flatMap { PeerNameColor(rawValue: $0) }, profileBackgroundEmojiId: profileBackgroundEmojiId, subscriberCount: subscriberCount, verificationIconFileId: verificationIconFileId)
case let .userEmpty(id):
case let .userEmpty(userEmptyData):
let id = userEmptyData.id
self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil, verificationIconFileId: nil)
}
}
static func merge(_ lhs: TelegramUser?, rhs: Api.User) -> TelegramUser? {
switch rhs {
case let .user(flags, _, _, rhsAccessHash, _, _, _, _, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, _, _, color, profileColor, subscriberCount, _, _):
case let .user(userData):
let (flags, _, _, rhsAccessHash, _, _, _, _, photo, _, _, restrictionReason, botInlinePlaceholder, _, emojiStatus, _, _, color, profileColor, subscriberCount, _, _) = (userData.flags, userData.flags2, userData.id, userData.accessHash, userData.firstName, userData.lastName, userData.username, userData.phone, userData.photo, userData.status, userData.botInfoVersion, userData.restrictionReason, userData.botInlinePlaceholder, userData.langCode, userData.emojiStatus, userData.usernames, userData.storiesMaxId, userData.color, userData.profileColor, userData.botActiveUsers, userData.botVerificationIcon, userData.sendPaidMessagesStars)
let isMin = (flags & (1 << 20)) != 0
if !isMin {
return TelegramUser(user: rhs)
@@ -256,12 +268,14 @@ extension TelegramUser {
var backgroundEmojiId: Int64?
if let color {
switch color {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
if let color {
nameColor = .preset(PeerNameColor(rawValue: color))
}
backgroundEmojiId = backgroundEmojiIdValue
case let .peerColorCollectible(_, collectibleId, giftEmojiId, backgroundEmojiIdValue, accentColor, colors, darkAccentColor, darkColors):
case let .peerColorCollectible(peerColorCollectibleData):
let (_, collectibleId, giftEmojiId, backgroundEmojiIdValue, accentColor, colors, darkAccentColor, darkColors) = (peerColorCollectibleData.flags, peerColorCollectibleData.collectibleId, peerColorCollectibleData.giftEmojiId, peerColorCollectibleData.backgroundEmojiId, peerColorCollectibleData.accentColor, peerColorCollectibleData.colors, peerColorCollectibleData.darkAccentColor, peerColorCollectibleData.darkColors)
nameColor = .collectible(PeerCollectibleColor(
collectibleId: collectibleId,
giftEmojiFileId: giftEmojiId,
@@ -276,12 +290,13 @@ extension TelegramUser {
break
}
}
var profileColorIndex: Int32?
var profileBackgroundEmojiId: Int64?
if let profileColor = profileColor {
switch profileColor {
case let .peerColor(_, color, backgroundEmojiIdValue):
case let .peerColor(peerColorData):
let (_, color, backgroundEmojiIdValue) = (peerColorData.flags, peerColorData.color, peerColorData.backgroundEmojiId)
profileColorIndex = color
profileBackgroundEmojiId = backgroundEmojiIdValue
default:
@@ -8,17 +8,22 @@ extension TelegramUserPresence {
switch apiStatus {
case .userStatusEmpty:
self.init(status: .none, lastActivity: 0)
case let .userStatusOnline(expires):
case let .userStatusOnline(userStatusOnlineData):
let (expires) = (userStatusOnlineData.expires)
self.init(status: .present(until: expires), lastActivity: 0)
case let .userStatusOffline(wasOnline):
case let .userStatusOffline(userStatusOfflineData):
let (wasOnline) = (userStatusOfflineData.wasOnline)
self.init(status: .present(until: wasOnline), lastActivity: 0)
case let .userStatusRecently(flags):
case let .userStatusRecently(userStatusRecentlyData):
let (flags) = (userStatusRecentlyData.flags)
let isHidden = (flags & (1 << 0)) != 0
self.init(status: .recently(isHidden: isHidden), lastActivity: 0)
case let .userStatusLastWeek(flags):
case let .userStatusLastWeek(userStatusLastWeekData):
let (flags) = (userStatusLastWeekData.flags)
let isHidden = (flags & (1 << 0)) != 0
self.init(status: .lastWeek(isHidden: isHidden), lastActivity: 0)
case let .userStatusLastMonth(flags):
case let .userStatusLastMonth(userStatusLastMonthData):
let (flags) = (userStatusLastMonthData.flags)
let isHidden = (flags & (1 << 0)) != 0
self.init(status: .lastMonth(isHidden: isHidden), lastActivity: 0)
}
@@ -26,7 +31,8 @@ extension TelegramUserPresence {
convenience init?(apiUser: Api.User) {
switch apiUser {
case let .user(_, _, _, _, _, _, _, _, _, status, _, _, _, _, _, _, _, _, _, _, _, _):
case let .user(userData):
let status = userData.status
if let status = status {
self.init(apiStatus: status)
} else {
@@ -13,47 +13,47 @@ func apiEntitiesFromMessageTextEntities(_ entities: [MessageTextEntity], associa
case .Unknown:
break
case .Mention:
apiEntities.append(.messageEntityMention(offset: offset, length: length))
apiEntities.append(.messageEntityMention(.init(offset: offset, length: length)))
case .Hashtag:
apiEntities.append(.messageEntityHashtag(offset: offset, length: length))
apiEntities.append(.messageEntityHashtag(.init(offset: offset, length: length)))
case .BotCommand:
apiEntities.append(.messageEntityBotCommand(offset: offset, length: length))
apiEntities.append(.messageEntityBotCommand(.init(offset: offset, length: length)))
case .Url:
apiEntities.append(.messageEntityUrl(offset: offset, length: length))
apiEntities.append(.messageEntityUrl(.init(offset: offset, length: length)))
case .Email:
apiEntities.append(.messageEntityEmail(offset: offset, length: length))
apiEntities.append(.messageEntityEmail(.init(offset: offset, length: length)))
case .Bold:
apiEntities.append(.messageEntityBold(offset: offset, length: length))
apiEntities.append(.messageEntityBold(.init(offset: offset, length: length)))
case .Italic:
apiEntities.append(.messageEntityItalic(offset: offset, length: length))
apiEntities.append(.messageEntityItalic(.init(offset: offset, length: length)))
case .Code:
apiEntities.append(.messageEntityCode(offset: offset, length: length))
apiEntities.append(.messageEntityCode(.init(offset: offset, length: length)))
case let .Pre(language):
apiEntities.append(.messageEntityPre(offset: offset, length: length, language: language ?? ""))
apiEntities.append(.messageEntityPre(.init(offset: offset, length: length, language: language ?? "")))
case let .TextUrl(url):
apiEntities.append(.messageEntityTextUrl(offset: offset, length: length, url: 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(offset: offset, length: length, userId: inputUser))
apiEntities.append(.inputMessageEntityMentionName(.init(offset: offset, length: length, userId: inputUser)))
}
case .PhoneNumber:
break
case .Strikethrough:
apiEntities.append(.messageEntityStrike(offset: offset, length: length))
apiEntities.append(.messageEntityStrike(.init(offset: offset, length: length)))
case let .BlockQuote(isCollapsed):
var flags: Int32 = 0
if isCollapsed {
flags |= 1 << 0
}
apiEntities.append(.messageEntityBlockquote(flags: flags, offset: offset, length: length))
apiEntities.append(.messageEntityBlockquote(.init(flags: flags, offset: offset, length: length)))
case .Underline:
apiEntities.append(.messageEntityUnderline(offset: offset, length: length))
apiEntities.append(.messageEntityUnderline(.init(offset: offset, length: length)))
case .BankCard:
apiEntities.append(.messageEntityBankCard(offset: offset, length: length))
apiEntities.append(.messageEntityBankCard(.init(offset: offset, length: length)))
case .Spoiler:
apiEntities.append(.messageEntitySpoiler(offset: offset, length: length))
apiEntities.append(.messageEntitySpoiler(.init(offset: offset, length: length)))
case let .CustomEmoji(_, fileId):
apiEntities.append(.messageEntityCustomEmoji(offset: offset, length: length, documentId: fileId))
apiEntities.append(.messageEntityCustomEmoji(.init(offset: offset, length: length, documentId: fileId)))
case .Custom:
break
}
@@ -7,7 +7,8 @@ import TelegramApi
extension TelegramTheme {
convenience init(apiTheme: Api.Theme) {
switch apiTheme {
case let .theme(flags, id, accessHash, slug, title, document, settings, emoticon, installCount):
case let .theme(themeData):
let (flags, id, accessHash, slug, title, document, settings, emoticon, installCount) = (themeData.flags, themeData.id, themeData.accessHash, themeData.slug, themeData.title, themeData.document, themeData.settings, themeData.emoticon, themeData.installsCount)
self.init(id: id, accessHash: accessHash, slug: slug, emoticon: emoticon, title: title, file: document.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }, settings: settings?.compactMap(TelegramThemeSettings.init(apiThemeSettings:)), isCreator: (flags & 1 << 0) != 0, isDefault: (flags & 1 << 1) != 0, installCount: installCount)
}
}
@@ -46,7 +47,8 @@ extension TelegramBaseTheme {
extension TelegramThemeSettings {
convenience init?(apiThemeSettings: Api.ThemeSettings) {
switch apiThemeSettings {
case let .themeSettings(flags, baseTheme, accentColor, outboxAccentColor, messageColors, wallpaper):
case let .themeSettings(themeSettingsData):
let (flags, baseTheme, accentColor, outboxAccentColor, messageColors, wallpaper) = (themeSettingsData.flags, themeSettingsData.baseTheme, themeSettingsData.accentColor, themeSettingsData.outboxAccentColor, themeSettingsData.messageColors, themeSettingsData.wallpaper)
self.init(baseTheme: TelegramBaseTheme(apiBaseTheme: baseTheme), accentColor: UInt32(bitPattern: accentColor), outgoingAccentColor: outboxAccentColor.flatMap { UInt32(bitPattern: $0) }, messageColors: messageColors?.map(UInt32.init(bitPattern:)) ?? [], animateMessageColors: (flags & 1 << 2) != 0, wallpaper: wallpaper.flatMap(TelegramWallpaper.init(apiWallpaper:)))
}
}
@@ -73,6 +75,6 @@ extension TelegramThemeSettings {
flags |= 1 << 1
}
return .inputThemeSettings(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: Int32(bitPattern: self.accentColor), outboxAccentColor: self.outgoingAccentColor.flatMap { Int32(bitPattern: $0) }, messageColors: self.messageColors.isEmpty ? nil : self.messageColors.map(Int32.init(bitPattern:)), wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings)
return .inputThemeSettings(.init(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: Int32(bitPattern: self.accentColor), outboxAccentColor: self.outgoingAccentColor.flatMap { Int32(bitPattern: $0) }, messageColors: self.messageColors.isEmpty ? nil : self.messageColors.map(Int32.init(bitPattern:)), wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings))
}
}
@@ -7,7 +7,8 @@ import TelegramApi
extension WallpaperSettings {
init(apiWallpaperSettings: Api.WallPaperSettings) {
switch apiWallpaperSettings {
case let .wallPaperSettings(flags, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, intensity, rotation, emoticon):
case let .wallPaperSettings(wallPaperSettingsData):
let (flags, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, intensity, rotation, emoticon) = (wallPaperSettingsData.flags, wallPaperSettingsData.backgroundColor, wallPaperSettingsData.secondBackgroundColor, wallPaperSettingsData.thirdBackgroundColor, wallPaperSettingsData.fourthBackgroundColor, wallPaperSettingsData.intensity, wallPaperSettingsData.rotation, wallPaperSettingsData.emoticon)
var colors: [UInt32] = []
if let backgroundColor = backgroundColor {
colors.append(UInt32(bitPattern: backgroundColor))
@@ -60,13 +61,14 @@ func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPap
flags |= (1 << 6)
fourthBackgroundColor = Int32(bitPattern: wallpaperSettings.colors[3])
}
return .wallPaperSettings(flags: flags, backgroundColor: backgroundColor, secondBackgroundColor: secondBackgroundColor, thirdBackgroundColor: thirdBackgroundColor, fourthBackgroundColor: fourthBackgroundColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation ?? 0, emoticon: wallpaperSettings.emoticon)
return .wallPaperSettings(.init(flags: flags, backgroundColor: backgroundColor, secondBackgroundColor: secondBackgroundColor, thirdBackgroundColor: thirdBackgroundColor, fourthBackgroundColor: fourthBackgroundColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation ?? 0, emoticon: wallpaperSettings.emoticon))
}
extension TelegramWallpaper {
init(apiWallpaper: Api.WallPaper) {
switch apiWallpaper {
case let .wallPaper(id, flags, accessHash, slug, document, settings):
case let .wallPaper(wallPaperData):
let (id, flags, accessHash, slug, document, settings) = (wallPaperData.id, wallPaperData.flags, wallPaperData.accessHash, wallPaperData.slug, wallPaperData.document, wallPaperData.settings)
if let file = telegramMediaFileFromApiDocument(document, altDocuments: []) {
let wallpaperSettings: WallpaperSettings
if let settings = settings {
@@ -79,8 +81,10 @@ extension TelegramWallpaper {
//assertionFailure()
self = .color(0xffffff)
}
case let .wallPaperNoFile(id, _, settings):
if let settings = settings, case let .wallPaperSettings(_, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, _, rotation, emoticon) = settings {
case let .wallPaperNoFile(wallPaperNoFileData):
let (id, _, settings) = (wallPaperNoFileData.id, wallPaperNoFileData.flags, wallPaperNoFileData.settings)
if let settings = settings, case let .wallPaperSettings(wallPaperSettingsData) = settings {
let (_, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, _, rotation, emoticon) = (wallPaperSettingsData.flags, wallPaperSettingsData.backgroundColor, wallPaperSettingsData.secondBackgroundColor, wallPaperSettingsData.thirdBackgroundColor, wallPaperSettingsData.fourthBackgroundColor, wallPaperSettingsData.intensity, wallPaperSettingsData.rotation, wallPaperSettingsData.emoticon)
if id == 0, let emoticon = emoticon {
self = .emoticon(emoticon)
return
@@ -107,13 +111,13 @@ extension TelegramWallpaper {
case .builtin:
return nil
case let .file(file):
return (.inputWallPaperSlug(slug: file.slug), apiWallpaperSettings(file.settings))
return (.inputWallPaperSlug(.init(slug: file.slug)), apiWallpaperSettings(file.settings))
case let .color(color):
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(colors: [color])))
return (.inputWallPaperNoFile(.init(id: 0)), apiWallpaperSettings(WallpaperSettings(colors: [color])))
case let .gradient(gradient):
return (.inputWallPaperNoFile(id: gradient.id ?? 0), apiWallpaperSettings(WallpaperSettings(colors: gradient.colors, rotation: gradient.settings.rotation)))
return (.inputWallPaperNoFile(.init(id: gradient.id ?? 0)), apiWallpaperSettings(WallpaperSettings(colors: gradient.colors, rotation: gradient.settings.rotation)))
case let .emoticon(emoticon):
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(emoticon: emoticon)))
return (.inputWallPaperNoFile(.init(id: 0)), apiWallpaperSettings(WallpaperSettings(emoticon: emoticon)))
default:
return nil
}