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 148302 additions and 62355 deletions
@@ -59,7 +59,8 @@ public final class SuggestedPostMessageAttribute: Equatable, MessageAttribute {
extension SuggestedPostMessageAttribute {
convenience init(apiSuggestedPost: Api.SuggestedPost) {
switch apiSuggestedPost {
case let .suggestedPost(flags, starsAmount, scheduleDate):
case let .suggestedPost(suggestedPostData):
let (flags, starsAmount, scheduleDate) = (suggestedPostData.flags, suggestedPostData.price, suggestedPostData.scheduleDate)
var state: State?
if (flags & (1 << 1)) != 0 {
state = .accepted
@@ -95,7 +96,7 @@ extension SuggestedPostMessageAttribute {
flags |= 1 << 3
price = amount.apiAmount
}
return .suggestedPost(flags: flags, price: price, scheduleDate: timestamp)
return .suggestedPost(.init(flags: flags, price: price, scheduleDate: timestamp))
}
}
@@ -1,29 +1,42 @@
import Foundation
import Postbox
import SGWebSettingsScheme
import SGGHSettingsScheme
public struct AppConfiguration: Codable, Equatable {
// MARK: Swiftgram
public var sgWebSettings: SGWebSettings
public var sgGHSettings: SGGHSettings
public var data: JSON?
public var hash: Int32
public static var defaultValue: AppConfiguration {
return AppConfiguration(data: nil, hash: 0)
return AppConfiguration(sgWebSettings: SGWebSettings.defaultValue, sgGHSettings: SGGHSettings.defaultValue, data: nil, hash: 0)
}
init(data: JSON?, hash: Int32) {
init(sgWebSettings: SGWebSettings, sgGHSettings: SGGHSettings, data: JSON?, hash: Int32) {
self.sgWebSettings = sgWebSettings
self.sgGHSettings = sgGHSettings
self.data = data
self.hash = hash
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.sgWebSettings = (try container.decodeIfPresent(SGWebSettings.self, forKey: "sg")) ?? SGWebSettings.defaultValue
self.sgGHSettings = (try container.decodeIfPresent(SGGHSettings.self, forKey: "sggh")) ?? SGGHSettings.defaultValue
self.data = try container.decodeIfPresent(JSON.self, forKey: "data")
self.hash = (try container.decodeIfPresent(Int32.self, forKey: "storedHash")) ?? 0
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.sgWebSettings, forKey: "sg")
try container.encode(self.sgGHSettings, forKey: "sggh")
try container.encodeIfPresent(self.data, forKey: "data")
try container.encode(self.hash, forKey: "storedHash")
}
@@ -89,7 +89,8 @@ extension PeerAllowedReactions {
switch apiReactions {
case .chatReactionsAll:
self = .all
case let .chatReactionsSome(reactions):
case let .chatReactionsSome(chatReactionsSomeData):
let reactions = chatReactionsSomeData.reactions
self = .limited(reactions.compactMap(MessageReaction.Reaction.init(apiReaction:)))
case .chatReactionsNone:
self = .empty
@@ -559,9 +559,11 @@ public struct PeerEmojiStatus: Equatable, Codable {
extension PeerEmojiStatus {
init?(apiStatus: Api.EmojiStatus) {
switch apiStatus {
case let .emojiStatus(_, documentId, until):
case let .emojiStatus(emojiStatusData):
let (documentId, until) = (emojiStatusData.documentId, emojiStatusData.until)
self.init(content: .emoji(fileId: documentId), expirationDate: until)
case let .emojiStatusCollectible(_, collectibleId, documentId, title, slug, patternDocumentId, centerColor, edgeColor, patternColor, textColor, until):
case let .emojiStatusCollectible(emojiStatusCollectibleData):
let (collectibleId, documentId, title, slug, patternDocumentId, centerColor, edgeColor, patternColor, textColor, until) = (emojiStatusCollectibleData.collectibleId, emojiStatusCollectibleData.documentId, emojiStatusCollectibleData.title, emojiStatusCollectibleData.slug, emojiStatusCollectibleData.patternDocumentId, emojiStatusCollectibleData.centerColor, emojiStatusCollectibleData.edgeColor, emojiStatusCollectibleData.patternColor, emojiStatusCollectibleData.textColor, emojiStatusCollectibleData.until)
self.init(content: .starGift(id: collectibleId, fileId: documentId, title: title, slug: slug, patternFileId: patternDocumentId, innerColor: centerColor, outerColor: edgeColor, patternColor: patternColor, textColor: textColor), expirationDate: until)
case .emojiStatusEmpty, .inputEmojiStatusCollectible:
return nil
@@ -826,33 +828,36 @@ public final class TelegramBusinessLocation: Equatable, Codable {
extension TelegramBusinessHours.WorkingTimeInterval {
init(apiInterval: Api.BusinessWeeklyOpen) {
switch apiInterval {
case let .businessWeeklyOpen(startMinute, endMinute):
case let .businessWeeklyOpen(businessWeeklyOpenData):
let (startMinute, endMinute) = (businessWeeklyOpenData.startMinute, businessWeeklyOpenData.endMinute)
self.init(startMinute: Int(startMinute), endMinute: Int(endMinute))
}
}
var apiInterval: Api.BusinessWeeklyOpen {
return .businessWeeklyOpen(startMinute: Int32(clamping: self.startMinute), endMinute: Int32(clamping: self.endMinute))
return .businessWeeklyOpen(Api.BusinessWeeklyOpen.Cons_businessWeeklyOpen(startMinute: Int32(clamping: self.startMinute), endMinute: Int32(clamping: self.endMinute)))
}
}
extension TelegramBusinessHours {
convenience init(apiWorkingHours: Api.BusinessWorkHours) {
switch apiWorkingHours {
case let .businessWorkHours(_, timezoneId, weeklyOpen):
case let .businessWorkHours(businessWorkHoursData):
let (_, timezoneId, weeklyOpen) = (businessWorkHoursData.flags, businessWorkHoursData.timezoneId, businessWorkHoursData.weeklyOpen)
self.init(timezoneId: timezoneId, weeklyTimeIntervals: weeklyOpen.map(TelegramBusinessHours.WorkingTimeInterval.init(apiInterval:)))
}
}
var apiBusinessHours: Api.BusinessWorkHours {
return .businessWorkHours(flags: 0, timezoneId: self.timezoneId, weeklyOpen: self.weeklyTimeIntervals.map(\.apiInterval))
return .businessWorkHours(Api.BusinessWorkHours.Cons_businessWorkHours(flags: 0, timezoneId: self.timezoneId, weeklyOpen: self.weeklyTimeIntervals.map(\.apiInterval)))
}
}
extension TelegramBusinessLocation.Coordinates {
init?(apiGeoPoint: Api.GeoPoint) {
switch apiGeoPoint {
case let .geoPoint(_, long, lat, _, _):
case let .geoPoint(geoPointData):
let (_, long, lat, _, _) = (geoPointData.flags, geoPointData.long, geoPointData.lat, geoPointData.accessHash, geoPointData.accuracyRadius)
self.init(latitude: lat, longitude: long)
case .geoPointEmpty:
return nil
@@ -860,14 +865,15 @@ extension TelegramBusinessLocation.Coordinates {
}
var apiInputGeoPoint: Api.InputGeoPoint {
return .inputGeoPoint(flags: 0, lat: self.latitude, long: self.longitude, accuracyRadius: nil)
return .inputGeoPoint(.init(flags: 0, lat: self.latitude, long: self.longitude, accuracyRadius: nil))
}
}
extension TelegramBusinessLocation {
convenience init(apiLocation: Api.BusinessLocation) {
switch apiLocation {
case let .businessLocation(_, geoPoint, address):
case let .businessLocation(businessLocationData):
let (_, geoPoint, address) = (businessLocationData.flags, businessLocationData.geoPoint, businessLocationData.address)
self.init(address: address, coordinates: geoPoint.flatMap { Coordinates(apiGeoPoint: $0) })
}
}
@@ -932,7 +938,8 @@ public final class TelegramBusinessChatLinks: Codable, Equatable {
extension TelegramBusinessChatLinks.Link {
convenience init(apiLink: Api.BusinessChatLink) {
switch apiLink {
case let .businessChatLink(_, link, message, entities, title, views):
case let .businessChatLink(businessChatLinkData):
let (_, link, message, entities, title, views) = (businessChatLinkData.flags, businessChatLinkData.link, businessChatLinkData.message, businessChatLinkData.entities, businessChatLinkData.title, businessChatLinkData.views)
self.init(url: link, message: message, entities: messageTextEntitiesFromApiEntities(entities ?? []), title: title, viewCount: views)
}
}
@@ -941,7 +948,8 @@ extension TelegramBusinessChatLinks.Link {
extension TelegramBusinessChatLinks {
static func fromApiLinks(apiLinks: Api.account.BusinessChatLinks) -> (result: TelegramBusinessChatLinks, users: [Api.User], chats: [Api.Chat]) {
switch apiLinks {
case let .businessChatLinks(links, chats, users):
case let .businessChatLinks(businessChatLinksData):
let (links, chats, users) = (businessChatLinksData.links, businessChatLinksData.chats, businessChatLinksData.users)
return (
TelegramBusinessChatLinks(links: links.map(Link.init(apiLink:))),
users,
@@ -989,7 +997,8 @@ public final class TelegramStarRefProgram: Codable, Equatable {
extension TelegramStarRefProgram {
convenience init(apiStarRefProgram: Api.StarRefProgram) {
switch apiStarRefProgram {
case let .starRefProgram(_, botId, commissionPermille, durationMonths, endDate, dailyRevenuePerUser):
case let .starRefProgram(starRefProgramData):
let (botId, commissionPermille, durationMonths, endDate, dailyRevenuePerUser) = (starRefProgramData.botId, starRefProgramData.commissionPermille, starRefProgramData.durationMonths, starRefProgramData.endDate, starRefProgramData.dailyRevenuePerUser)
self.init(botId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)), commissionPermille: commissionPermille, durationMonths: durationMonths, endDate: endDate, dailyRevenuePerUser: dailyRevenuePerUser.flatMap(StarsAmount.init(apiAmount:)))
}
}
@@ -1103,7 +1112,8 @@ extension TelegramProfileTab {
extension TelegramStarRating {
convenience init(apiRating: Api.StarsRating) {
switch apiRating {
case let .starsRating(_, level, currentLevelStars, stars, nextLevelStars):
case let .starsRating(starsRatingData):
let (level, currentLevelStars, stars, nextLevelStars) = (starsRatingData.level, starsRatingData.currentLevelStars, starsRatingData.stars, starsRatingData.nextLevelStars)
self.init(
level: level,
currentLevelStars: currentLevelStars,
@@ -1922,7 +1932,7 @@ func _internal_createBusinessChatLink(account: Account, message: String, entitie
flags |= 1 << 1
}
return account.network.request(Api.functions.account.createBusinessChatLink(link: .inputBusinessChatLink(flags: flags, message: message, entities: apiEntities, title: title)))
return account.network.request(Api.functions.account.createBusinessChatLink(link: .inputBusinessChatLink(.init(flags: flags, message: message, entities: apiEntities, title: title))))
|> mapError { error -> AddBusinessChatLinkError in
if error.errorDescription == "CHATLINKS_TOO_MUCH" {
return .tooManyLinks
@@ -1962,7 +1972,7 @@ func _internal_editBusinessChatLink(account: Account, url: String, message: Stri
flags |= 1 << 1
}
return account.network.request(Api.functions.account.editBusinessChatLink(slug: url, link: .inputBusinessChatLink(flags: flags, message: message, entities: apiEntities, title: title)))
return account.network.request(Api.functions.account.editBusinessChatLink(slug: url, link: .inputBusinessChatLink(.init(flags: flags, message: message, entities: apiEntities, title: title))))
|> mapError { _ -> AddBusinessChatLinkError in
return .generic
}
@@ -714,7 +714,7 @@ public final class WebFileReferenceMediaResource: TelegramMediaResource, MediaRe
}
var apiInputLocation: Api.InputWebFileLocation {
return .inputWebFileLocation(url: self.url, accessHash: self.accessHash)
return .inputWebFileLocation(.init(url: self.url, accessHash: self.accessHash))
}
}
@@ -762,7 +762,7 @@ final class AlbumCoverResource: TelegramMediaResource, MediaResourceWithWebFileR
var flags: Int32 = 0
var document: Api.InputDocument?
if let file = self.file, let resource = file.media.resource as? CloudDocumentMediaResource {
document = .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))
document = .inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())))
flags |= 1 << 0
}
var requestTitle: String?
@@ -775,12 +775,12 @@ final class AlbumCoverResource: TelegramMediaResource, MediaResourceWithWebFileR
if self.isThumbnail {
flags |= 1 << 2
}
return .inputWebFileAudioAlbumThumbLocation(
return .inputWebFileAudioAlbumThumbLocation(.init(
flags: flags,
document: document,
title: requestTitle,
performer: requestPerformer
)
))
}
}
@@ -183,9 +183,11 @@ extension MessageReaction.Reaction {
switch apiReaction {
case .reactionEmpty:
return nil
case let .reactionEmoji(emoticon):
case let .reactionEmoji(reactionEmojiData):
let emoticon = reactionEmojiData.emoticon
self = .builtin(emoticon)
case let .reactionCustomEmoji(documentId):
case let .reactionCustomEmoji(reactionCustomEmojiData):
let documentId = reactionCustomEmojiData.documentId
self = .custom(documentId)
case .reactionPaid:
self = .stars
@@ -195,9 +197,9 @@ extension MessageReaction.Reaction {
var apiReaction: Api.Reaction {
switch self {
case let .builtin(value):
return .reactionEmoji(emoticon: value)
return .reactionEmoji(.init(emoticon: value))
case let .custom(fileId):
return .reactionCustomEmoji(documentId: fileId)
return .reactionCustomEmoji(.init(documentId: fileId))
case .stars:
return .reactionPaid
}
@@ -1,4 +1,5 @@
import Postbox
import TelegramApi
public enum ReplyMarkupButtonRequestPeerType: Codable, Equatable {
enum CodingKeys: String, CodingKey {
@@ -323,21 +324,79 @@ public enum ReplyMarkupButtonAction: PostboxCoding, Equatable {
}
}
extension ReplyMarkupButton.Style {
init(apiStyle: Api.KeyboardButtonStyle) {
switch apiStyle {
case let .keyboardButtonStyle(keyboardButtonStyle):
var color: Color?
if keyboardButtonStyle.flags & (1 << 0) != 0 {
color = .primary
} else if keyboardButtonStyle.flags & (1 << 1) != 0 {
color = .danger
} else if keyboardButtonStyle.flags & (1 << 2) != 0 {
color = .success
}
self.init(color: color, iconFileId: keyboardButtonStyle.icon)
}
}
}
public struct ReplyMarkupButton: PostboxCoding, Equatable {
public struct Style: PostboxCoding, Equatable {
public enum Color: Int32 {
case primary = 0
case danger = 1
case success = 2
}
public let color: Color?
public let iconFileId: Int64?
public init(color: Color?, iconFileId: Int64?) {
self.color = color
self.iconFileId = iconFileId
}
public init(decoder: PostboxDecoder) {
let rawColor = decoder.decodeInt32ForKey("c", orElse: -1)
if rawColor != -1 {
self.color = Color(rawValue: rawColor)
} else {
self.color = nil
}
self.iconFileId = decoder.decodeOptionalInt64ForKey("i")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.color?.rawValue ?? -1, forKey: "c")
if let iconFileId = self.iconFileId {
encoder.encodeInt64(iconFileId, forKey: "i")
} else {
encoder.encodeNil(forKey: "i")
}
}
}
public let title: String
public let titleWhenForwarded: String?
public let action: ReplyMarkupButtonAction
public let style: Style?
public init(title: String, titleWhenForwarded: String?, action: ReplyMarkupButtonAction) {
public init(title: String, titleWhenForwarded: String?, action: ReplyMarkupButtonAction, style: Style?) {
self.title = title
self.titleWhenForwarded = titleWhenForwarded
self.action = action
self.style = style
}
public init(decoder: PostboxDecoder) {
self.title = decoder.decodeStringForKey(".t", orElse: "")
self.titleWhenForwarded = decoder.decodeOptionalStringForKey(".tf")
self.action = ReplyMarkupButtonAction(decoder: decoder)
self.style = (decoder.decodeObjectForKey(".stl", decoder: { Style(decoder: $0) }) as? Style)
}
public func encode(_ encoder: PostboxEncoder) {
@@ -348,10 +407,15 @@ public struct ReplyMarkupButton: PostboxCoding, Equatable {
encoder.encodeNil(forKey: ".tf")
}
self.action.encode(encoder)
if let style = self.style {
encoder.encodeObject(style, forKey: ".stl")
} else {
encoder.encodeNil(forKey: ".stl")
}
}
public static func ==(lhs: ReplyMarkupButton, rhs: ReplyMarkupButton) -> Bool {
return lhs.title == rhs.title && lhs.action == rhs.action
return lhs.title == rhs.title && lhs.action == rhs.action && lhs.style == rhs.style
}
}
@@ -399,6 +463,21 @@ public class ReplyMarkupMessageAttribute: MessageAttribute, Equatable {
public let flags: ReplyMarkupMessageFlags
public let placeholder: String?
public var associatedMediaIds: [MediaId] {
var result: [MediaId] = []
for row in rows {
for button in row.buttons {
if let iconFileId = button.style?.iconFileId {
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: iconFileId)
if !result.contains(mediaId) {
result.append(mediaId)
}
}
}
}
return result
}
public init(rows: [ReplyMarkupRow], flags: ReplyMarkupMessageFlags, placeholder: String?) {
self.rows = rows
self.flags = flags
@@ -117,7 +117,8 @@ public class QuotedReplyMessageAttribute: MessageAttribute {
extension QuotedReplyMessageAttribute {
convenience init(apiHeader: Api.MessageFwdHeader, quote: EngineMessageReplyQuote?, isQuote: Bool) {
switch apiHeader {
case let .messageFwdHeader(_, fromId, fromName, _, _, _, _, _, _, _, _, _):
case let .messageFwdHeader(messageFwdHeaderData):
let (_, fromId, fromName, _, _, _, _, _, _, _, _, _) = (messageFwdHeaderData.flags, messageFwdHeaderData.fromId, messageFwdHeaderData.fromName, messageFwdHeaderData.date, messageFwdHeaderData.channelPost, messageFwdHeaderData.postAuthor, messageFwdHeaderData.savedFromPeer, messageFwdHeaderData.savedFromMsgId, messageFwdHeaderData.savedFromId, messageFwdHeaderData.savedFromName, messageFwdHeaderData.savedDate, messageFwdHeaderData.psaType)
self.init(peerId: fromId?.peerId, authorName: fromName, quote: quote, isQuote: isQuote)
}
}
@@ -211,6 +211,38 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
public static let isFinal = StarGiftAuctionBidFlags(rawValue: 1 << 3)
}
public struct GroupCreatorChange: Codable, Equatable {
private enum CodingKeys: String, CodingKey {
case kind = "k"
case targetPeerId = "t"
}
public enum Kind: Int32 {
case pending = 0
case applied = 1
}
public let kind: Kind
public let targetPeerId: PeerId
public init(kind: Kind, targetPeerId: PeerId) {
self.kind = kind
self.targetPeerId = targetPeerId
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.kind = Kind(rawValue: try container.decode(Int32.self, forKey: .kind)) ?? .pending
self.targetPeerId = PeerId(try container.decode(Int64.self, forKey: .targetPeerId))
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.kind.rawValue, forKey: .kind)
try container.encode(self.targetPeerId.toInt64(), forKey: .targetPeerId)
}
}
case unknown
case groupCreated(title: String)
case addedMembers(peerIds: [PeerId])
@@ -256,7 +288,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case giftStars(currency: String, amount: Int64, count: Int64, cryptoCurrency: String?, cryptoAmount: Int64?, transactionId: String?)
case prizeStars(amount: Int64, isUnclaimed: Bool, boostPeerId: PeerId?, transactionId: String?, giveawayMessageId: MessageId?)
case starGift(gift: StarGift, convertStars: Int64?, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, converted: Bool, upgraded: Bool, canUpgrade: Bool, upgradeStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, upgradeMessageId: Int32?, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, prepaidUpgradeHash: String?, giftMessageId: Int32?, upgradeSeparate: Bool, isAuctionAcquired: Bool, toPeerId: EnginePeer.Id?, number: Int32?)
case starGiftUnique(gift: StarGift, isUpgrade: Bool, isTransferred: Bool, savedToProfile: Bool, canExportDate: Int32?, transferStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, resaleAmount: CurrencyAmount?, canTransferDate: Int32?, canResaleDate: Int32?, dropOriginalDetailsStars: Int64?, assigned: Bool, fromOffer: Bool)
case starGiftUnique(gift: StarGift, isUpgrade: Bool, isTransferred: Bool, savedToProfile: Bool, canExportDate: Int32?, transferStars: Int64?, isRefunded: Bool, isPrepaidUpgrade: Bool, peerId: EnginePeer.Id?, senderId: EnginePeer.Id?, savedId: Int64?, resaleAmount: CurrencyAmount?, canTransferDate: Int32?, canResaleDate: Int32?, dropOriginalDetailsStars: Int64?, assigned: Bool, fromOffer: Bool, canCraftAt: Int32?, isCrafted: Bool)
case paidMessagesRefunded(count: Int32, stars: Int64)
case paidMessagesPriceEdited(stars: Int64, broadcastMessagesAllowed: Bool)
case conferenceCall(ConferenceCall)
@@ -269,6 +301,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case suggestedBirthday(TelegramBirthday)
case starGiftPurchaseOffer(gift: StarGift, amount: CurrencyAmount, expireDate: Int32, isAccepted: Bool, isDeclined: Bool)
case starGiftPurchaseOfferDeclined(gift: StarGift, amount: CurrencyAmount, hasExpired: Bool)
case groupCreatorChange(GroupCreatorChange)
public init(decoder: PostboxDecoder) {
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
@@ -404,7 +437,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
} else if let stars = decoder.decodeOptionalInt64ForKey("resaleStars") {
resaleAmount = CurrencyAmount(amount: StarsAmount(value: stars, nanos: 0), currency: .stars)
}
self = .starGiftUnique(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, isUpgrade: decoder.decodeBoolForKey("isUpgrade", orElse: false), isTransferred: decoder.decodeBoolForKey("isTransferred", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), canExportDate: decoder.decodeOptionalInt32ForKey("canExportDate"), transferStars: decoder.decodeOptionalInt64ForKey("transferStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), resaleAmount: resaleAmount, canTransferDate: decoder.decodeOptionalInt32ForKey("canTransferDate"), canResaleDate: decoder.decodeOptionalInt32ForKey("canResaleDate"), dropOriginalDetailsStars: decoder.decodeOptionalInt64ForKey("dropOriginalDetailsStars"), assigned: decoder.decodeBoolForKey("assigned", orElse: false), fromOffer: decoder.decodeBoolForKey("fromOffer", orElse: false))
self = .starGiftUnique(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, isUpgrade: decoder.decodeBoolForKey("isUpgrade", orElse: false), isTransferred: decoder.decodeBoolForKey("isTransferred", orElse: false), savedToProfile: decoder.decodeBoolForKey("savedToProfile", orElse: false), canExportDate: decoder.decodeOptionalInt32ForKey("canExportDate"), transferStars: decoder.decodeOptionalInt64ForKey("transferStars"), isRefunded: decoder.decodeBoolForKey("isRefunded", orElse: false), isPrepaidUpgrade: decoder.decodeBoolForKey("isPrepaidUpgrade", orElse: false), peerId: decoder.decodeOptionalInt64ForKey("peerId").flatMap { EnginePeer.Id($0) }, senderId: decoder.decodeOptionalInt64ForKey("senderId").flatMap { EnginePeer.Id($0) }, savedId: decoder.decodeOptionalInt64ForKey("savedId"), resaleAmount: resaleAmount, canTransferDate: decoder.decodeOptionalInt32ForKey("canTransferDate"), canResaleDate: decoder.decodeOptionalInt32ForKey("canResaleDate"), dropOriginalDetailsStars: decoder.decodeOptionalInt64ForKey("dropOriginalDetailsStars"), assigned: decoder.decodeBoolForKey("assigned", orElse: false), fromOffer: decoder.decodeBoolForKey("fromOffer", orElse: false), canCraftAt: decoder.decodeOptionalInt32ForKey("canCraftAt"), isCrafted: decoder.decodeBoolForKey("isCrafted", orElse: false))
case 46:
self = .paidMessagesRefunded(count: decoder.decodeInt32ForKey("count", orElse: 0), stars: decoder.decodeInt64ForKey("stars", orElse: 0))
case 47:
@@ -437,9 +470,11 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case 55:
self = .suggestedBirthday(decoder.decodeCodable(TelegramBirthday.self, forKey: "birthday") ?? TelegramBirthday(day: 1, month: 1, year: nil))
case 56:
self = .starGiftPurchaseOffer(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount")!, expireDate: decoder.decodeInt32ForKey("expireDate", orElse: 0), isAccepted: decoder.decodeBoolForKey("isAccepted", orElse: false), isDeclined: decoder.decodeBoolForKey("isDeclined", orElse: false))
self = .starGiftPurchaseOffer(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount") ?? CurrencyAmount(amount: .zero, currency: .stars), expireDate: decoder.decodeInt32ForKey("expireDate", orElse: 0), isAccepted: decoder.decodeBoolForKey("isAccepted", orElse: false), isDeclined: decoder.decodeBoolForKey("isDeclined", orElse: false))
case 57:
self = .starGiftPurchaseOfferDeclined(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount")!, hasExpired: decoder.decodeBoolForKey("hasExpired", orElse: false))
case 59:
self = .groupCreatorChange(decoder.decodeCodable(GroupCreatorChange.self, forKey: "d") ?? GroupCreatorChange(kind: .pending, targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0))))
default:
self = .unknown
}
@@ -803,7 +838,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
} else {
encoder.encodeNil(forKey: "number")
}
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars, assigned, fromOffer):
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, isRefunded, isPrepaidUpgrade, peerId, senderId, savedId, resaleAmount, canTransferDate, canResaleDate, dropOriginalDetailsStars, assigned, fromOffer, canCraftAt, isCrafted):
encoder.encodeInt32(45, forKey: "_rawValue")
encoder.encodeObject(gift, forKey: "gift")
encoder.encodeBool(isUpgrade, forKey: "isUpgrade")
@@ -858,6 +893,14 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
}
encoder.encodeBool(assigned, forKey: "assigned")
encoder.encodeBool(fromOffer, forKey: "fromOffer")
if let canCraftAt {
encoder.encodeInt32(canCraftAt, forKey: "canCraftAt")
} else {
encoder.encodeNil(forKey: "canCraftAt")
}
encoder.encodeBool(isCrafted, forKey: "isCrafted")
case let .paidMessagesRefunded(count, stars):
encoder.encodeInt32(46, forKey: "_rawValue")
encoder.encodeInt32(count, forKey: "count")
@@ -923,6 +966,9 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
encoder.encodeObject(gift, forKey: "gift")
encoder.encodeCodable(amount, forKey: "amount")
encoder.encodeBool(hasExpired, forKey: "hasExpired")
case let .groupCreatorChange(groupCreatorChange):
encoder.encodeInt32(59, forKey: "_rawValue")
encoder.encodeCodable(groupCreatorChange, forKey: "d")
}
}
@@ -965,7 +1011,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
peerIds.append(toPeerId)
}
return peerIds
case let .starGiftUnique(gift, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, _, _):
case let .starGiftUnique(gift, _, _, _, _, _, _, _, peerId, senderId, _, _, _, _, _, _, _, _, _):
var peerIds: [PeerId] = []
if let peerId {
peerIds.append(peerId)
@@ -979,6 +1025,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
return peerIds
case let .conferenceCall(conferenceCall):
return conferenceCall.otherParticipants
case let .groupCreatorChange(groupCreatorChange):
return [groupCreatorChange.targetPeerId]
default:
return []
}
@@ -43,6 +43,7 @@ public struct BotUserInfoFlags: OptionSet {
public static let isBusiness = BotUserInfoFlags(rawValue: (1 << 6))
public static let hasWebApp = BotUserInfoFlags(rawValue: (1 << 7))
public static let hasForum = BotUserInfoFlags(rawValue: (1 << 8))
public static let forumManagedByUser = BotUserInfoFlags(rawValue: (1 << 9))
}
public struct BotUserInfo: PostboxCoding, Equatable {
@@ -86,3 +86,47 @@ public class TranslationMessageAttribute: MessageAttribute, Equatable {
return true
}
}
// MARK: Swiftgram
public class QuickTranslationMessageAttribute: MessageAttribute, Equatable {
public let originalText: String
public let originalEntities: [MessageTextEntity]
public var associatedPeerIds: [PeerId] {
return []
}
public init(
text: String,
entities: [MessageTextEntity]
) {
self.originalText = text
self.originalEntities = entities
}
required public init(decoder: PostboxDecoder) {
self.originalText = decoder.decodeStringForKey("originalText", orElse: "")
self.originalEntities = decoder.decodeObjectArrayWithDecoderForKey("originalEntities")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.originalText, forKey: "originalText")
encoder.encodeObjectArray(self.originalEntities, forKey: "originalEntities")
}
public static func ==(lhs: QuickTranslationMessageAttribute, rhs: QuickTranslationMessageAttribute) -> Bool {
if lhs.originalText != rhs.originalText {
return false
}
if lhs.originalEntities != rhs.originalEntities {
return false
}
return true
}
}