Stars subscriptions API [skip ci]

This commit is contained in:
Ilya Laktyushin 2024-07-22 20:45:32 +04:00
parent 31ba87fb0f
commit ea1e9e797f
21 changed files with 639 additions and 155 deletions

View File

@ -1,4 +1,4 @@
import Foundation
wimport Foundation
import UIKit
import AsyncDisplayKit
import Display
@ -460,7 +460,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
let actionsDisposable = DisposableSet()
let initialState: InviteLinkEditControllerState
if let invite = invite, case let .link(_, title, _, requestApproval, _, _, _, _, expireDate, usageLimit, count, _) = invite {
if let invite = invite, case let .link(_, title, _, requestApproval, _, _, _, _, expireDate, usageLimit, count, _, _) = invite {
var usageLimit = usageLimit
if let limit = usageLimit, let count = count, count > 0 {
usageLimit = limit - count
@ -593,7 +593,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
let requestNeeded = state.requestApproval && !isPublic
if invite == nil {
let _ = (context.engine.peers.createPeerExportedInvitation(peerId: peerId, title: title, expireDate: expireDate, usageLimit: requestNeeded ? 0 : usageLimit, requestNeeded: requestNeeded)
let _ = (context.engine.peers.createPeerExportedInvitation(peerId: peerId, title: title, expireDate: expireDate, usageLimit: requestNeeded ? 0 : usageLimit, requestNeeded: requestNeeded, subscriptionPricing: nil)
|> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic))
|> deliverOnMainQueue).start(next: { invite in
completion?(invite)
@ -606,7 +606,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
}
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
})
} else if let initialInvite = invite, case let .link(link, _, _, initialRequestApproval, _, _, _, _, initialExpireDate, initialUsageLimit, _, _) = initialInvite {
} else if let initialInvite = invite, case let .link(link, _, _, initialRequestApproval, _, _, _, _, initialExpireDate, initialUsageLimit, _, _, _) = initialInvite {
if initialExpireDate == expireDate && initialUsageLimit == usageLimit && initialRequestApproval == requestNeeded {
completion?(initialInvite)
dismissImpl?()

View File

@ -284,7 +284,7 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
let mainInvite: ExportedInvitation?
var isPublic = false
if let peer = peer, let address = peer.addressName, !address.isEmpty && admin == nil {
mainInvite = .link(link: "t.me/\(address)", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: EnginePeer.Id(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil)
mainInvite = .link(link: "t.me/\(address)", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: EnginePeer.Id(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil, pricing: nil)
isPublic = true
} else if let invites = invites, let invite = invites.first(where: { $0.isPermanent && !$0.isRevoked }) {
mainInvite = invite
@ -299,7 +299,7 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
let importersCount: Int32
if let count = importers?.count {
importersCount = count
} else if let mainInvite = mainInvite, case let .link(_, _, _, _, _, _, _, _, _, _, count, _) = mainInvite, let count = count {
} else if let mainInvite = mainInvite, case let .link(_, _, _, _, _, _, _, _, _, _, count, _, _) = mainInvite, let count = count {
importersCount = count
} else {
importersCount = 0
@ -338,7 +338,7 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData,
if let additionalInvites = additionalInvites {
var index: Int32 = 0
for invite in additionalInvites {
if case let .link(_, _, _, _, _, _, _, _, expireDate, _, _, _) = invite {
if case let .link(_, _, _, _, _, _, _, _, expireDate, _, _, _, _) = invite {
entries.append(.link(index, presentationData.theme, invite, canEditLinks, expireDate != nil ? tick : nil))
index += 1
}
@ -533,7 +533,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
})
})))
if case let .link(_, _, _, _, _, adminId, _, _, _, _, _, _) = invite, adminId.toInt64() != 0 {
if case let .link(_, _, _, _, _, adminId, _, _, _, _, _, _, _) = invite, adminId.toInt64() != 0 {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.InviteLink_ContextRevoke, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { _, f in

View File

@ -425,7 +425,7 @@ public final class InviteLinkViewController: ViewController {
self.controller = controller
self.importersContext = importersContext ?? context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: false))
if case let .link(_, _, _, requestApproval, _, _, _, _, _, _, _, _) = invite, requestApproval {
if case let .link(_, _, _, requestApproval, _, _, _, _, _, _, _, _, _) = invite, requestApproval {
self.requestsContext = context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: true))
} else {
self.requestsContext = nil
@ -568,7 +568,7 @@ public final class InviteLinkViewController: ViewController {
}
var creatorIsBot: Signal<Bool, NoError>
if case let .link(_, _, _, _, _, adminId, _, _, _, _, _, _) = invite {
if case let .link(_, _, _, _, _, adminId, _, _, _, _, _, _, _) = invite {
creatorIsBot = context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: adminId))
|> map { peer -> Bool in
if let peer, case let .user(user) = peer, user.botInfo != nil {
@ -716,7 +716,7 @@ public final class InviteLinkViewController: ViewController {
requestsState = .single(PeerInvitationImportersState.Empty)
}
if case let .link(_, _, _, _, _, adminId, date, _, _, usageLimit, _, _) = invite {
if case let .link(_, _, _, _, _, adminId, date, _, _, usageLimit, _, _, _) = invite {
self.disposable = (combineLatest(
self.presentationDataPromise.get(),
self.importersContext.state,
@ -1002,7 +1002,7 @@ public final class InviteLinkViewController: ViewController {
var subtitleText = ""
var subtitleColor = self.presentationData.theme.list.itemSecondaryTextColor
if case let .link(_, title, _, _, isRevoked, _, _, _, expireDate, usageLimit, count, _) = self.invite {
if case let .link(_, title, _, _, isRevoked, _, _, _, expireDate, usageLimit, count, _, _) = self.invite {
if isRevoked {
subtitleText = self.presentationData.strings.InviteLink_Revoked
} else if let usageLimit = usageLimit, let count = count, count >= usageLimit {

View File

@ -9,7 +9,7 @@ import ShimmerEffect
import TelegramCore
func invitationAvailability(_ invite: ExportedInvitation) -> CGFloat {
if case let .link(_, _, _, _, isRevoked, _, date, startDate, expireDate, usageLimit, count, _) = invite {
if case let .link(_, _, _, _, isRevoked, _, date, startDate, expireDate, usageLimit, count, _, _) = invite {
if isRevoked {
return 0.0
}
@ -299,7 +299,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
let color: ItemBackgroundColor
let nextColor: ItemBackgroundColor
let transitionFraction: CGFloat
if let invite = item.invite, case let .link(_, _, _, _, isRevoked, _, _, _, expireDate, usageLimit, _, _) = invite {
if let invite = item.invite, case let .link(_, _, _, _, isRevoked, _, _, _, expireDate, usageLimit, _, _, _) = invite {
if isRevoked {
color = .gray
nextColor = .gray
@ -346,7 +346,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
var timerValue: TimerNode.Value?
if let invite = item.invite, case let .link(_, title, _, _, _, _, date, startDate, expireDate, usageLimit, count, requestedCount) = invite {
if let invite = item.invite, case let .link(_, title, _, _, _, _, date, startDate, expireDate, usageLimit, count, requestedCount, _) = invite {
if let title = title, !title.isEmpty {
titleText = title
}

View File

@ -1024,7 +1024,7 @@ private enum StatsEntry: ItemListNodeEntry {
case let .boostOverview(_, stats, isGroup):
return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: isGroup, stats: stats, sectionId: self.section, style: .blocks)
case let .boostLink(_, link):
let invite: ExportedInvitation = .link(link: link, title: nil, isPermanent: false, requestApproval: false, isRevoked: false, adminId: PeerId(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil)
let invite: ExportedInvitation = .link(link: link, title: nil, isPermanent: false, requestApproval: false, isRevoked: false, adminId: PeerId(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil, pricing: nil)
return ItemListPermanentInviteLinkItem(context: arguments.context, presentationData: presentationData, invite: invite, count: 0, peers: [], displayButton: true, displayImporters: false, buttonColor: nil, sectionId: self.section, style: .blocks, copyAction: {
arguments.copyBoostLink(link)
}, shareAction: {

View File

@ -201,7 +201,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
dict[-1146407795] = { return Api.ChatFull.parse_channelFull($0) }
dict[640893467] = { return Api.ChatFull.parse_chatFull($0) }
dict[-840897472] = { return Api.ChatInvite.parse_chatInvite($0) }
dict[-1965998484] = { return Api.ChatInvite.parse_chatInvite($0) }
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
dict[-1940201511] = { return Api.ChatInviteImporter.parse_chatInviteImporter($0) }
@ -273,7 +273,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1038136962] = { return Api.EncryptedFile.parse_encryptedFileEmpty($0) }
dict[-317144808] = { return Api.EncryptedMessage.parse_encryptedMessage($0) }
dict[594758406] = { return Api.EncryptedMessage.parse_encryptedMessageService($0) }
dict[179611673] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
dict[-1812799720] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
dict[-317687113] = { return Api.ExportedChatInvite.parse_chatInvitePublicJoinRequests($0) }
dict[206668204] = { return Api.ExportedChatlistInvite.parse_exportedChatlistInvite($0) }
dict[1103040667] = { return Api.ExportedContactToken.parse_exportedContactToken($0) }
@ -370,6 +370,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1210199983] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
dict[-659913713] = { return Api.InputGroupCall.parse_inputGroupCall($0) }
dict[887591921] = { return Api.InputInvoice.parse_inputInvoiceChatInviteSubscription($0) }
dict[-977967015] = { return Api.InputInvoice.parse_inputInvoiceMessage($0) }
dict[-1734841331] = { return Api.InputInvoice.parse_inputInvoicePremiumGiftCode($0) }
dict[-1020867857] = { return Api.InputInvoice.parse_inputInvoiceSlug($0) }
@ -879,8 +880,10 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
dict[1577421297] = { return Api.StarsGiftOption.parse_starsGiftOption($0) }
dict[2033461574] = { return Api.StarsRevenueStatus.parse_starsRevenueStatus($0) }
dict[-797707802] = { return Api.StarsSubscription.parse_starsSubscription($0) }
dict[88173912] = { return Api.StarsSubscriptionPricing.parse_starsSubscriptionPricing($0) }
dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) }
dict[766853519] = { return Api.StarsTransaction.parse_starsTransaction($0) }
dict[455361027] = { return Api.StarsTransaction.parse_starsTransaction($0) }
dict[-670195363] = { return Api.StarsTransactionPeer.parse_starsTransactionPeer($0) }
dict[1617438738] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAds($0) }
dict[-1269320843] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAppStore($0) }
@ -1325,7 +1328,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) }
dict[-919881925] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) }
dict[497778871] = { return Api.payments.StarsRevenueWithdrawalUrl.parse_starsRevenueWithdrawalUrl($0) }
dict[-1930105248] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
dict[-2064727699] = { return Api.payments.StarsStatus.parse_starsStatus($0) }
dict[-784000893] = { return Api.payments.ValidatedRequestedInfo.parse_validatedRequestedInfo($0) }
dict[541839704] = { return Api.phone.ExportedGroupCallInvite.parse_exportedGroupCallInvite($0) }
dict[-1636664659] = { return Api.phone.GroupCall.parse_groupCall($0) }
@ -1996,6 +1999,10 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.StarsRevenueStatus:
_1.serialize(buffer, boxed)
case let _1 as Api.StarsSubscription:
_1.serialize(buffer, boxed)
case let _1 as Api.StarsSubscriptionPricing:
_1.serialize(buffer, boxed)
case let _1 as Api.StarsTopupOption:
_1.serialize(buffer, boxed)
case let _1 as Api.StarsTransaction:

View File

@ -670,6 +670,102 @@ public extension Api {
}
}
public extension Api {
enum StarsSubscription: TypeConstructorDescription {
case starsSubscription(flags: Int32, id: String, peer: Api.Peer, untilDate: Int32, pricing: Api.StarsSubscriptionPricing)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing):
if boxed {
buffer.appendInt32(-797707802)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(id, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(untilDate, buffer: buffer, boxed: false)
pricing.serialize(buffer, true)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .starsSubscription(let flags, let id, let peer, let untilDate, let pricing):
return ("starsSubscription", [("flags", flags as Any), ("id", id as Any), ("peer", peer as Any), ("untilDate", untilDate as Any), ("pricing", pricing as Any)])
}
}
public static func parse_starsSubscription(_ reader: BufferReader) -> StarsSubscription? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: Api.Peer?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _4: Int32?
_4 = reader.readInt32()
var _5: Api.StarsSubscriptionPricing?
if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.StarsSubscription.starsSubscription(flags: _1!, id: _2!, peer: _3!, untilDate: _4!, pricing: _5!)
}
else {
return nil
}
}
}
}
public extension Api {
enum StarsSubscriptionPricing: TypeConstructorDescription {
case starsSubscriptionPricing(period: Int32, amount: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .starsSubscriptionPricing(let period, let amount):
if boxed {
buffer.appendInt32(88173912)
}
serializeInt32(period, buffer: buffer, boxed: false)
serializeInt64(amount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .starsSubscriptionPricing(let period, let amount):
return ("starsSubscriptionPricing", [("period", period as Any), ("amount", amount as Any)])
}
}
public static func parse_starsSubscriptionPricing(_ reader: BufferReader) -> StarsSubscriptionPricing? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.StarsSubscriptionPricing.starsSubscriptionPricing(period: _1!, amount: _2!)
}
else {
return nil
}
}
}
}
public extension Api {
enum StarsTopupOption: TypeConstructorDescription {
case starsTopupOption(flags: Int32, stars: Int64, storeProduct: String?, currency: String, amount: Int64)
@ -724,13 +820,13 @@ public extension Api {
}
public extension Api {
enum StarsTransaction: TypeConstructorDescription {
case starsTransaction(flags: Int32, id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?)
case starsTransaction(flags: Int32, id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?, transactionDate: Int32?, transactionUrl: String?, botPayload: Buffer?, msgId: Int32?, extendedMedia: [Api.MessageMedia]?, subscriptionPeriod: Int32?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia):
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod):
if boxed {
buffer.appendInt32(766853519)
buffer.appendInt32(455361027)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(id, buffer: buffer, boxed: false)
@ -749,14 +845,15 @@ public extension Api {
for item in extendedMedia! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(subscriptionPeriod!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia):
return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any)])
case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo, let transactionDate, let transactionUrl, let botPayload, let msgId, let extendedMedia, let subscriptionPeriod):
return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("transactionDate", transactionDate as Any), ("transactionUrl", transactionUrl as Any), ("botPayload", botPayload as Any), ("msgId", msgId as Any), ("extendedMedia", extendedMedia as Any), ("subscriptionPeriod", subscriptionPeriod as Any)])
}
}
@ -793,6 +890,8 @@ public extension Api {
if Int(_1!) & Int(1 << 9) != 0 {if let _ = reader.readInt32() {
_13 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageMedia.self)
} }
var _14: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_14 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -806,8 +905,9 @@ public extension Api {
let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil
let _c12 = (Int(_1!) & Int(1 << 8) == 0) || _12 != nil
let _c13 = (Int(_1!) & Int(1 << 9) == 0) || _13 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13)
let _c14 = (Int(_1!) & Int(1 << 11) == 0) || _14 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8, transactionDate: _9, transactionUrl: _10, botPayload: _11, msgId: _12, extendedMedia: _13, subscriptionPeriod: _14)
}
else {
return nil

View File

@ -1246,21 +1246,27 @@ public extension Api.payments {
}
public extension Api.payments {
enum StarsStatus: TypeConstructorDescription {
case starsStatus(flags: Int32, balance: Int64, history: [Api.StarsTransaction], nextOffset: String?, chats: [Api.Chat], users: [Api.User])
case starsStatus(flags: Int32, balance: Int64, subscriptions: [Api.StarsSubscription]?, subscriptionsNextOffset: String?, history: [Api.StarsTransaction]?, nextOffset: String?, chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .starsStatus(let flags, let balance, let history, let nextOffset, let chats, let users):
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let history, let nextOffset, let chats, let users):
if boxed {
buffer.appendInt32(-1930105248)
buffer.appendInt32(-2064727699)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(balance, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(history.count))
for item in history {
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(subscriptions!.count))
for item in subscriptions! {
item.serialize(buffer, true)
}
}}
if Int(flags) & Int(1 << 2) != 0 {serializeString(subscriptionsNextOffset!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(history!.count))
for item in history! {
item.serialize(buffer, true)
}}
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(chats.count))
@ -1278,8 +1284,8 @@ public extension Api.payments {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .starsStatus(let flags, let balance, let history, let nextOffset, let chats, let users):
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
case .starsStatus(let flags, let balance, let subscriptions, let subscriptionsNextOffset, let history, let nextOffset, let chats, let users):
return ("starsStatus", [("flags", flags as Any), ("balance", balance as Any), ("subscriptions", subscriptions as Any), ("subscriptionsNextOffset", subscriptionsNextOffset as Any), ("history", history as Any), ("nextOffset", nextOffset as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
@ -1288,28 +1294,36 @@ public extension Api.payments {
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: [Api.StarsTransaction]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
}
var _3: [Api.StarsSubscription]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsSubscription.self)
} }
var _4: String?
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
var _5: [Api.Chat]?
if Int(_1!) & Int(1 << 2) != 0 {_4 = parseString(reader) }
var _5: [Api.StarsTransaction]?
if Int(_1!) & Int(1 << 3) != 0 {if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarsTransaction.self)
} }
var _6: String?
if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) }
var _7: [Api.Chat]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _6: [Api.User]?
var _8: [Api.User]?
if let _ = reader.readInt32() {
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, history: _3!, nextOffset: _4, chats: _5!, users: _6!)
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil
let _c7 = _7 != nil
let _c8 = _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.payments.StarsStatus.starsStatus(flags: _1!, balance: _2!, subscriptions: _3, subscriptionsNextOffset: _4, history: _5, nextOffset: _6, chats: _7!, users: _8!)
}
else {
return nil

View File

@ -5439,15 +5439,16 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?, title: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
static func exportChatInvite(flags: Int32, peer: Api.InputPeer, expireDate: Int32?, usageLimit: Int32?, title: String?, subscriptionPricing: Api.StarsSubscriptionPricing?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.ExportedChatInvite>) {
let buffer = Buffer()
buffer.appendInt32(-1607670315)
buffer.appendInt32(-1537876336)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(expireDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(usageLimit!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 4) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("expireDate", String(describing: expireDate)), ("usageLimit", String(describing: usageLimit)), ("title", String(describing: title))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
if Int(flags) & Int(1 << 5) != 0 {subscriptionPricing!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.exportChatInvite", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("expireDate", String(describing: expireDate)), ("usageLimit", String(describing: usageLimit)), ("title", String(describing: title)), ("subscriptionPricing", String(describing: subscriptionPricing))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.ExportedChatInvite? in
let reader = BufferReader(buffer)
var result: Api.ExportedChatInvite?
if let signature = reader.readInt32() {
@ -8735,6 +8736,24 @@ public extension Api.functions.payments {
})
}
}
public extension Api.functions.payments {
static func changeStarsSubscription(flags: Int32, peer: Api.InputPeer, subscriptionId: String, canceled: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-948500360)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeString(subscriptionId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {canceled!.serialize(buffer, true)}
return (FunctionDescription(name: "payments.changeStarsSubscription", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("subscriptionId", String(describing: subscriptionId)), ("canceled", String(describing: canceled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.payments {
static func checkGiftCode(slug: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.CheckedGiftCode>) {
let buffer = Buffer()
@ -8954,6 +8973,22 @@ public extension Api.functions.payments {
})
}
}
public extension Api.functions.payments {
static func getStarsSubscriptions(peer: Api.InputPeer, offset: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.payments.StarsStatus>) {
let buffer = Buffer()
buffer.appendInt32(-2145547570)
peer.serialize(buffer, true)
serializeString(offset, buffer: buffer, boxed: false)
return (FunctionDescription(name: "payments.getStarsSubscriptions", parameters: [("peer", String(describing: peer)), ("offset", String(describing: offset))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.payments.StarsStatus? in
let reader = BufferReader(buffer)
var result: Api.payments.StarsStatus?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.payments.StarsStatus
}
return result
})
}
}
public extension Api.functions.payments {
static func getStarsTopupOptions() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.StarsTopupOption]>) {
let buffer = Buffer()

View File

@ -1280,15 +1280,15 @@ public extension Api {
}
public extension Api {
indirect enum ChatInvite: TypeConstructorDescription {
case chatInvite(flags: Int32, title: String, about: String?, photo: Api.Photo, participantsCount: Int32, participants: [Api.User]?, color: Int32)
case chatInvite(flags: Int32, title: String, about: String?, photo: Api.Photo, participantsCount: Int32, participants: [Api.User]?, color: Int32, subscriptionPricing: Api.StarsSubscriptionPricing?, subscriptionFormId: Int64?)
case chatInviteAlready(chat: Api.Chat)
case chatInvitePeek(chat: Api.Chat, expires: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color):
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color, let subscriptionPricing, let subscriptionFormId):
if boxed {
buffer.appendInt32(-840897472)
buffer.appendInt32(-1965998484)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
@ -1301,6 +1301,8 @@ public extension Api {
item.serialize(buffer, true)
}}
serializeInt32(color, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 10) != 0 {subscriptionPricing!.serialize(buffer, true)}
if Int(flags) & Int(1 << 10) != 0 {serializeInt64(subscriptionFormId!, buffer: buffer, boxed: false)}
break
case .chatInviteAlready(let chat):
if boxed {
@ -1320,8 +1322,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color):
return ("chatInvite", [("flags", flags as Any), ("title", title as Any), ("about", about as Any), ("photo", photo as Any), ("participantsCount", participantsCount as Any), ("participants", participants as Any), ("color", color as Any)])
case .chatInvite(let flags, let title, let about, let photo, let participantsCount, let participants, let color, let subscriptionPricing, let subscriptionFormId):
return ("chatInvite", [("flags", flags as Any), ("title", title as Any), ("about", about as Any), ("photo", photo as Any), ("participantsCount", participantsCount as Any), ("participants", participants as Any), ("color", color as Any), ("subscriptionPricing", subscriptionPricing as Any), ("subscriptionFormId", subscriptionFormId as Any)])
case .chatInviteAlready(let chat):
return ("chatInviteAlready", [("chat", chat as Any)])
case .chatInvitePeek(let chat, let expires):
@ -1348,6 +1350,12 @@ public extension Api {
} }
var _7: Int32?
_7 = reader.readInt32()
var _8: Api.StarsSubscriptionPricing?
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
} }
var _9: Int64?
if Int(_1!) & Int(1 << 10) != 0 {_9 = reader.readInt64() }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 5) == 0) || _3 != nil
@ -1355,8 +1363,10 @@ public extension Api {
let _c5 = _5 != nil
let _c6 = (Int(_1!) & Int(1 << 4) == 0) || _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.ChatInvite.chatInvite(flags: _1!, title: _2!, about: _3, photo: _4!, participantsCount: _5!, participants: _6, color: _7!)
let _c8 = (Int(_1!) & Int(1 << 10) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 10) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.ChatInvite.chatInvite(flags: _1!, title: _2!, about: _3, photo: _4!, participantsCount: _5!, participants: _6, color: _7!, subscriptionPricing: _8, subscriptionFormId: _9)
}
else {
return nil

View File

@ -1012,14 +1012,14 @@ public extension Api {
}
public extension Api {
enum ExportedChatInvite: TypeConstructorDescription {
case chatInviteExported(flags: Int32, link: String, adminId: Int64, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, usage: Int32?, requested: Int32?, title: String?)
case chatInviteExported(flags: Int32, link: String, adminId: Int64, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, usage: Int32?, requested: Int32?, title: String?, subscriptionPricing: Api.StarsSubscriptionPricing?)
case chatInvitePublicJoinRequests
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title):
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title, let subscriptionPricing):
if boxed {
buffer.appendInt32(179611673)
buffer.appendInt32(-1812799720)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(link, buffer: buffer, boxed: false)
@ -1031,6 +1031,7 @@ public extension Api {
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(usage!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 7) != 0 {serializeInt32(requested!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 8) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 9) != 0 {subscriptionPricing!.serialize(buffer, true)}
break
case .chatInvitePublicJoinRequests:
if boxed {
@ -1043,8 +1044,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title):
return ("chatInviteExported", [("flags", flags as Any), ("link", link as Any), ("adminId", adminId as Any), ("date", date as Any), ("startDate", startDate as Any), ("expireDate", expireDate as Any), ("usageLimit", usageLimit as Any), ("usage", usage as Any), ("requested", requested as Any), ("title", title as Any)])
case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title, let subscriptionPricing):
return ("chatInviteExported", [("flags", flags as Any), ("link", link as Any), ("adminId", adminId as Any), ("date", date as Any), ("startDate", startDate as Any), ("expireDate", expireDate as Any), ("usageLimit", usageLimit as Any), ("usage", usage as Any), ("requested", requested as Any), ("title", title as Any), ("subscriptionPricing", subscriptionPricing as Any)])
case .chatInvitePublicJoinRequests:
return ("chatInvitePublicJoinRequests", [])
}
@ -1071,6 +1072,10 @@ public extension Api {
if Int(_1!) & Int(1 << 7) != 0 {_9 = reader.readInt32() }
var _10: String?
if Int(_1!) & Int(1 << 8) != 0 {_10 = parseString(reader) }
var _11: Api.StarsSubscriptionPricing?
if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() {
_11 = Api.parse(reader, signature: signature) as? Api.StarsSubscriptionPricing
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -1081,8 +1086,9 @@ public extension Api {
let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 7) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 8) == 0) || _10 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.ExportedChatInvite.chatInviteExported(flags: _1!, link: _2!, adminId: _3!, date: _4!, startDate: _5, expireDate: _6, usageLimit: _7, usage: _8, requested: _9, title: _10)
let _c11 = (Int(_1!) & Int(1 << 9) == 0) || _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.ExportedChatInvite.chatInviteExported(flags: _1!, link: _2!, adminId: _3!, date: _4!, startDate: _5, expireDate: _6, usageLimit: _7, usage: _8, requested: _9, title: _10, subscriptionPricing: _11)
}
else {
return nil

View File

@ -1004,6 +1004,7 @@ public extension Api {
}
public extension Api {
indirect enum InputInvoice: TypeConstructorDescription {
case inputInvoiceChatInviteSubscription(hash: String)
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
case inputInvoicePremiumGiftCode(purpose: Api.InputStorePaymentPurpose, option: Api.PremiumGiftCodeOption)
case inputInvoiceSlug(slug: String)
@ -1011,6 +1012,12 @@ public extension Api {
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inputInvoiceChatInviteSubscription(let hash):
if boxed {
buffer.appendInt32(887591921)
}
serializeString(hash, buffer: buffer, boxed: false)
break
case .inputInvoiceMessage(let peer, let msgId):
if boxed {
buffer.appendInt32(-977967015)
@ -1042,6 +1049,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inputInvoiceChatInviteSubscription(let hash):
return ("inputInvoiceChatInviteSubscription", [("hash", hash as Any)])
case .inputInvoiceMessage(let peer, let msgId):
return ("inputInvoiceMessage", [("peer", peer as Any), ("msgId", msgId as Any)])
case .inputInvoicePremiumGiftCode(let purpose, let option):
@ -1053,6 +1062,17 @@ public extension Api {
}
}
public static func parse_inputInvoiceChatInviteSubscription(_ reader: BufferReader) -> InputInvoice? {
var _1: String?
_1 = parseString(reader)
let _c1 = _1 != nil
if _c1 {
return Api.InputInvoice.inputInvoiceChatInviteSubscription(hash: _1!)
}
else {
return nil
}
}
public static func parse_inputInvoiceMessage(_ reader: BufferReader) -> InputInvoice? {
var _1: Api.InputPeer?
if let signature = reader.readInt32() {

View File

@ -6,8 +6,8 @@ import TelegramApi
extension ExportedInvitation {
init(apiExportedInvite: Api.ExportedChatInvite) {
switch apiExportedInvite {
case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title):
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)
case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title, pricing):
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:
self = .publicJoinRequest
}
@ -17,7 +17,7 @@ extension ExportedInvitation {
public extension ExportedInvitation {
var link: String? {
switch self {
case let .link(link, _, _, _, _, _, _, _, _, _, _, _):
case let .link(link, _, _, _, _, _, _, _, _, _, _, _, _):
return link
case .publicJoinRequest:
return nil
@ -26,7 +26,7 @@ public extension ExportedInvitation {
var date: Int32? {
switch self {
case let .link(_, _, _, _, _, _, date, _, _, _, _, _):
case let .link(_, _, _, _, _, _, date, _, _, _, _, _, _):
return date
case .publicJoinRequest:
return nil
@ -35,7 +35,7 @@ public extension ExportedInvitation {
var isPermanent: Bool {
switch self {
case let .link(_, _, isPermanent, _, _, _, _, _, _, _, _, _):
case let .link(_, _, isPermanent, _, _, _, _, _, _, _, _, _, _):
return isPermanent
case .publicJoinRequest:
return false
@ -44,10 +44,19 @@ public extension ExportedInvitation {
var isRevoked: Bool {
switch self {
case let .link(_, _, _, _, isRevoked, _, _, _, _, _, _, _):
case let .link(_, _, _, _, isRevoked, _, _, _, _, _, _, _, _):
return isRevoked
case .publicJoinRequest:
return false
}
}
var pricing: StarsSubscriptionPricing? {
switch self {
case let .link(_, _, _, _, _, _, _, _, _, _, _, _, pricing):
return pricing
case .publicJoinRequest:
return nil
}
}
}

View File

@ -1,7 +1,7 @@
import Postbox
public enum ExportedInvitation: Codable, Equatable {
case link(link: String, title: String?, isPermanent: Bool, requestApproval: Bool, isRevoked: Bool, adminId: PeerId, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, count: Int32?, requestedCount: Int32?)
case link(link: String, title: String?, isPermanent: Bool, requestApproval: Bool, isRevoked: Bool, adminId: PeerId, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, count: Int32?, requestedCount: Int32?, pricing: StarsSubscriptionPricing?)
case publicJoinRequest
public init(from decoder: Decoder) throws {
@ -21,8 +21,9 @@ public enum ExportedInvitation: Codable, Equatable {
let usageLimit = try container.decodeIfPresent(Int32.self, forKey: "usageLimit")
let count = try container.decodeIfPresent(Int32.self, forKey: "count")
let requestedCount = try? container.decodeIfPresent(Int32.self, forKey: "requestedCount")
let pricing = try? container.decodeIfPresent(StarsSubscriptionPricing.self, forKey: "pricing")
self = .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount)
self = .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount, pricing: pricing)
} else {
self = .publicJoinRequest
}
@ -32,7 +33,7 @@ public enum ExportedInvitation: Codable, Equatable {
var container = encoder.container(keyedBy: StringCodingKey.self)
switch self {
case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount):
case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount, pricing):
let type: Int32 = 0
try container.encode(type, forKey: "t")
try container.encode(link, forKey: "l")
@ -47,6 +48,7 @@ public enum ExportedInvitation: Codable, Equatable {
try container.encodeIfPresent(usageLimit, forKey: "usageLimit")
try container.encodeIfPresent(count, forKey: "count")
try container.encodeIfPresent(requestedCount, forKey: "requestedCount")
try container.encodeIfPresent(pricing, forKey: "pricing")
case .publicJoinRequest:
let type: Int32 = 1
try container.encode(type, forKey: "t")
@ -55,8 +57,8 @@ public enum ExportedInvitation: Codable, Equatable {
public static func ==(lhs: ExportedInvitation, rhs: ExportedInvitation) -> Bool {
switch lhs {
case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount):
if case .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount) = rhs {
case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount, pricing):
if case .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount, pricing) = rhs {
return true
} else {
return false
@ -72,8 +74,8 @@ public enum ExportedInvitation: Codable, Equatable {
public func withUpdated(isRevoked: Bool) -> ExportedInvitation {
switch self {
case let .link(link, title, isPermanent, requestApproval, _, adminId, date, startDate, expireDate, usageLimit, count, requestedCount):
return .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount)
case let .link(link, title, isPermanent, requestApproval, _, adminId, date, startDate, expireDate, usageLimit, count, requestedCount, pricing):
return .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount, pricing: pricing)
case .publicJoinRequest:
return .publicJoinRequest
}

View File

@ -11,6 +11,7 @@ public enum BotPaymentInvoiceSource {
case giftCode(users: [PeerId], currency: String, amount: Int64, option: PremiumGiftCodeOption)
case stars(option: StarsTopUpOption)
case starsGift(peerId: EnginePeer.Id, count: Int64, currency: String, amount: Int64)
case starsChatSubscription(hash: String)
}
public struct BotPaymentInvoiceFields: OptionSet {
@ -314,6 +315,8 @@ func _internal_parseInputInvoice(transaction: Transaction, source: BotPaymentInv
return nil
}
return .inputInvoiceStars(purpose: .inputStorePaymentStarsGift(userId: inputUser, stars: count, currency: currency, amount: amount))
case let .starsChatSubscription(hash):
return .inputInvoiceChatInviteSubscription(hash: hash)
}
}
@ -612,7 +615,7 @@ func _internal_sendBotPaymentForm(account: Account, formId: Int64, source: BotPa
receiptMessageId = id
}
}
case .giftCode, .stars, .starsGift:
case .giftCode, .stars, .starsGift, .starsChatSubscription:
receiptMessageId = nil
}
}

View File

@ -147,8 +147,10 @@ func _internal_starsGiftOptions(account: Account, peerId: EnginePeer.Id?) -> Sig
struct InternalStarsStatus {
let balance: Int64
let subscriptions: [StarsContext.State.Subscription]
let nextSubscriptionsOffset: String?
let transactions: [StarsContext.State.Transaction]
let nextOffset: String?
let nextTransactionsOffset: String?
}
private enum RequestStarsStateError {
@ -187,17 +189,25 @@ private func _internal_requestStarsState(account: Account, peerId: EnginePeer.Id
|> mapToSignal { result -> Signal<InternalStarsStatus, RequestStarsStateError> in
return account.postbox.transaction { transaction -> InternalStarsStatus in
switch result {
case let .starsStatus(_, balance, history, nextOffset, chats, users):
case let .starsStatus(_, balance, _, _, transactions, nextTransactionsOffset, chats, users):
let peers = AccumulatedPeers(chats: chats, users: users)
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers)
var parsedTransactions: [StarsContext.State.Transaction] = []
for entry in history {
if let parsedTransaction = StarsContext.State.Transaction(apiTransaction: entry, peerId: peerId != account.peerId ? peerId : nil, transaction: transaction) {
parsedTransactions.append(parsedTransaction)
if let transactions {
for entry in transactions {
if let parsedTransaction = StarsContext.State.Transaction(apiTransaction: entry, peerId: peerId != account.peerId ? peerId : nil, transaction: transaction) {
parsedTransactions.append(parsedTransaction)
}
}
}
return InternalStarsStatus(balance: balance, transactions: parsedTransactions, nextOffset: nextOffset)
return InternalStarsStatus(
balance: balance,
subscriptions: [],
nextSubscriptionsOffset: nil,
transactions: parsedTransactions,
nextTransactionsOffset: nextTransactionsOffset
)
}
}
|> castError(RequestStarsStateError.self)
@ -205,6 +215,51 @@ private func _internal_requestStarsState(account: Account, peerId: EnginePeer.Id
}
}
private enum RequestStarsSubscriptionsError {
case generic
}
private func _internal_requestStarsSubscriptions(account: Account, peerId: EnginePeer.Id, offset: String) -> Signal<InternalStarsStatus, RequestStarsSubscriptionsError> {
return account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(peerId)
}
|> castError(RequestStarsSubscriptionsError.self)
|> mapToSignal { peer -> Signal<InternalStarsStatus, RequestStarsSubscriptionsError> in
guard let peer, let inputPeer = apiInputPeer(peer) else {
return .fail(.generic)
}
return account.network.request(Api.functions.payments.getStarsSubscriptions(peer: inputPeer, offset: offset))
|> retryRequest
|> castError(RequestStarsSubscriptionsError.self)
|> mapToSignal { result -> Signal<InternalStarsStatus, RequestStarsSubscriptionsError> in
return account.postbox.transaction { transaction -> InternalStarsStatus in
switch result {
case let .starsStatus(_, balance, subscriptions, subscriptionsNextOffset, _, _, chats, users):
let peers = AccumulatedPeers(chats: chats, users: users)
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: peers)
var parsedSubscriptions: [StarsContext.State.Subscription] = []
if let subscriptions {
for entry in subscriptions {
if let parsedSubscription = StarsContext.State.Subscription(apiSubscription: entry, transaction: transaction) {
parsedSubscriptions.append(parsedSubscription)
}
}
}
return InternalStarsStatus(
balance: balance,
subscriptions: parsedSubscriptions,
nextSubscriptionsOffset: subscriptionsNextOffset,
transactions: [],
nextTransactionsOffset: nil
)
}
}
|> castError(RequestStarsSubscriptionsError.self)
}
}
}
private final class StarsContextImpl {
private let account: Account
fileprivate let peerId: EnginePeer.Id
@ -214,7 +269,6 @@ private final class StarsContextImpl {
var state: Signal<StarsContext.State?, NoError> {
return self._statePromise.get()
}
private var nextOffset: String?
private let disposable = MetaDisposable()
private var updateDisposable: Disposable?
@ -235,7 +289,7 @@ private final class StarsContextImpl {
guard let self, let state = self._state, let balance = balances[peerId] else {
return
}
self.updateState(StarsContext.State(flags: [], balance: balance, transactions: state.transactions, canLoadMore: nextOffset != nil, isLoading: false))
self.updateState(StarsContext.State(flags: [], balance: balance, subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: state.transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: false))
self.load(force: true)
})
}
@ -261,8 +315,7 @@ private final class StarsContextImpl {
guard let self else {
return
}
self.updateState(StarsContext.State(flags: [], balance: status.balance, transactions: status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false))
self.nextOffset = status.nextOffset
self.updateState(StarsContext.State(flags: [], balance: status.balance, subscriptions: status.subscriptions, canLoadMoreSubscriptions: status.nextSubscriptionsOffset != nil, transactions: status.transactions, canLoadMoreTransactions: status.nextTransactionsOffset != nil, isLoading: false))
}, error: { [weak self] _ in
guard let self else {
return
@ -280,32 +333,14 @@ private final class StarsContextImpl {
var transactions = state.transactions
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, media: []), at: 0)
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: state.balance + balance, transactions: transactions, canLoadMore: state.canLoadMore, isLoading: state.isLoading))
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: state.balance + balance, subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
}
fileprivate func updateBalance(_ balance: Int64, transactions: [StarsContext.State.Transaction]?) {
guard let state = self._state else {
return
}
self.updateState(StarsContext.State(flags: [], balance: balance, transactions: transactions ?? state.transactions, canLoadMore: state.canLoadMore, isLoading: state.isLoading))
}
func loadMore() {
assert(Queue.mainQueue().isCurrent())
guard let currentState = self._state, let nextOffset = self.nextOffset else {
return
}
self._state?.isLoading = true
self.disposable.set((_internal_requestStarsState(account: self.account, peerId: self.peerId, mode: .all, offset: nextOffset, limit: 10)
|> deliverOnMainQueue).start(next: { [weak self] status in
if let self {
self.updateState(StarsContext.State(flags: [], balance: status.balance, transactions: currentState.transactions + status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false))
self.nextOffset = status.nextOffset
}
}))
self.updateState(StarsContext.State(flags: [], balance: balance, subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions ?? state.transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
}
private func updateState(_ state: StarsContext.State) {
@ -317,7 +352,7 @@ private final class StarsContextImpl {
private extension StarsContext.State.Transaction {
init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) {
switch apiTransaction {
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia):
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod):
let parsedPeer: StarsContext.State.Transaction.Peer
var paidMessageId: MessageId?
switch transactionPeer {
@ -362,11 +397,28 @@ private extension StarsContext.State.Transaction {
}
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
let _ = subscriptionPeriod
self.init(flags: flags, id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, media: media)
}
}
}
private extension StarsContext.State.Subscription {
init?(apiSubscription: Api.StarsSubscription, transaction: Transaction) {
switch apiSubscription {
case let .starsSubscription(apiFlags, id, apiPeer, untilDate, pricing):
guard let peer = transaction.getPeer(apiPeer.peerId) else {
return nil
}
var flags: Flags = []
if (apiFlags & (1 << 0)) != 0 {
flags.insert(.isCancelled)
}
self.init(flags: flags, id: id, peer: EnginePeer(peer), untilDate: untilDate, pricing: StarsSubscriptionPricing(apiStarsSubscriptionPricing: pricing))
}
}
}
public final class StarsContext {
public struct State: Equatable {
public struct Transaction: Equatable {
@ -476,6 +528,57 @@ public final class StarsContext {
}
}
public struct Subscription: Equatable {
public struct Flags: OptionSet {
public var rawValue: Int32
public init(rawValue: Int32) {
self.rawValue = rawValue
}
public static let isCancelled = Flags(rawValue: 1 << 0)
}
public let flags: Flags
public let id: String
public let peer: EnginePeer
public let untilDate: Int32
public let pricing: StarsSubscriptionPricing
public init(
flags: Flags,
id: String,
peer: EnginePeer,
untilDate: Int32,
pricing: StarsSubscriptionPricing
) {
self.flags = flags
self.id = id
self.peer = peer
self.untilDate = untilDate
self.pricing = pricing
}
public static func == (lhs: Subscription, rhs: Subscription) -> Bool {
if lhs.flags != rhs.flags {
return false
}
if lhs.id != rhs.id {
return false
}
if lhs.peer != rhs.peer {
return false
}
if lhs.untilDate != rhs.untilDate {
return false
}
if lhs.pricing != rhs.pricing {
return false
}
return true
}
}
public struct Flags: OptionSet {
public var rawValue: Int32
@ -488,15 +591,19 @@ public final class StarsContext {
public var flags: Flags
public var balance: Int64
public var subscriptions: [Subscription]
public var canLoadMoreSubscriptions: Bool
public var transactions: [Transaction]
public var canLoadMore: Bool
public var canLoadMoreTransactions: Bool
public var isLoading: Bool
init(flags: Flags, balance: Int64, transactions: [Transaction], canLoadMore: Bool, isLoading: Bool) {
init(flags: Flags, balance: Int64, subscriptions: [Subscription], canLoadMoreSubscriptions: Bool, transactions: [Transaction], canLoadMoreTransactions: Bool, isLoading: Bool) {
self.flags = flags
self.balance = balance
self.subscriptions = subscriptions
self.canLoadMoreSubscriptions = canLoadMoreSubscriptions
self.transactions = transactions
self.canLoadMore = canLoadMore
self.canLoadMoreTransactions = canLoadMoreTransactions
self.isLoading = isLoading
}
@ -510,7 +617,10 @@ public final class StarsContext {
if lhs.transactions != rhs.transactions {
return false
}
if lhs.canLoadMore != rhs.canLoadMore {
if lhs.subscriptions != rhs.subscriptions {
return false
}
if lhs.canLoadMoreTransactions != rhs.canLoadMoreTransactions {
return false
}
if lhs.isLoading != rhs.isLoading {
@ -569,11 +679,6 @@ public final class StarsContext {
}
}
public func loadMore() {
self.impl.with {
$0.loadMore()
}
}
init(account: Account) {
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
@ -690,7 +795,7 @@ private final class StarsTransactionsContextImpl {
guard let self else {
return
}
self.nextOffset = status.nextOffset
self.nextOffset = status.nextTransactionsOffset
var updatedState = self._state
updatedState.transactions = nextOffset.isEmpty ? status.transactions : updatedState.transactions + status.transactions
@ -769,6 +874,112 @@ public final class StarsTransactionsContext {
}
}
private final class StarsSubscriptionsContextImpl {
private let account: Account
private weak var starsContext: StarsContext?
private var _state: StarsSubscriptionsContext.State
private let _statePromise = Promise<StarsSubscriptionsContext.State>()
var state: Signal<StarsSubscriptionsContext.State, NoError> {
return self._statePromise.get()
}
private var nextOffset: String? = ""
private let disposable = MetaDisposable()
private var stateDisposable: Disposable?
init(account: Account, starsContext: StarsContext) {
assert(Queue.mainQueue().isCurrent())
self.account = account
self.starsContext = starsContext
let currentSubscriptions = starsContext.currentState?.subscriptions ?? []
let canLoadMore = starsContext.currentState?.canLoadMoreSubscriptions ?? true
self._state = StarsSubscriptionsContext.State(subscriptions: currentSubscriptions, canLoadMore: canLoadMore, isLoading: false)
self._statePromise.set(.single(self._state))
}
deinit {
assert(Queue.mainQueue().isCurrent())
self.disposable.dispose()
self.stateDisposable?.dispose()
}
func loadMore() {
assert(Queue.mainQueue().isCurrent())
guard !self._state.isLoading, let nextOffset = self.nextOffset else {
return
}
var updatedState = self._state
updatedState.isLoading = true
self.updateState(updatedState)
self.disposable.set((_internal_requestStarsSubscriptions(account: self.account, peerId: self.account.peerId, offset: nextOffset)
|> deliverOnMainQueue).start(next: { [weak self] status in
guard let self else {
return
}
self.nextOffset = status.nextSubscriptionsOffset
var updatedState = self._state
updatedState.subscriptions = nextOffset.isEmpty ? status.subscriptions : updatedState.subscriptions + status.subscriptions
updatedState.isLoading = false
updatedState.canLoadMore = self.nextOffset != nil
self.updateState(updatedState)
}))
}
private func updateState(_ state: StarsSubscriptionsContext.State) {
self._state = state
self._statePromise.set(.single(state))
}
}
public final class StarsSubscriptionsContext {
public struct State: Equatable {
public var subscriptions: [StarsContext.State.Subscription]
public var canLoadMore: Bool
public var isLoading: Bool
init(subscriptions: [StarsContext.State.Subscription], canLoadMore: Bool, isLoading: Bool) {
self.subscriptions = subscriptions
self.canLoadMore = canLoadMore
self.isLoading = isLoading
}
}
fileprivate let impl: QueueLocalObject<StarsSubscriptionsContextImpl>
public var state: Signal<StarsSubscriptionsContext.State, NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
self.impl.with { impl in
disposable.set(impl.state.start(next: { value in
subscriber.putNext(value)
}))
}
return disposable
}
}
public func loadMore() {
self.impl.with {
$0.loadMore()
}
}
init(account: Account, starsContext: StarsContext) {
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
return StarsSubscriptionsContextImpl(account: account, starsContext: starsContext)
})
}
}
func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: BotPaymentInvoiceSource) -> Signal<SendBotPaymentResult, SendBotPaymentFormError> {
return account.postbox.transaction { transaction -> Api.InputInvoice? in
return _internal_parseInputInvoice(transaction: transaction, source: source)
@ -819,6 +1030,8 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
}
case .giftCode, .stars, .starsGift:
receiptMessageId = nil
case .starsChatSubscription:
receiptMessageId = nil
}
}
}
@ -889,7 +1102,7 @@ func _internal_getStarsTransaction(accountPeerId: PeerId, postbox: Postbox, netw
}
|> mapToSignal { result -> Signal<StarsContext.State.Transaction?, NoError> in
return postbox.transaction { transaction -> StarsContext.State.Transaction? in
guard let result, case let .starsStatus(_, _, transactions, _, chats, users) = result, let matchingTransaction = transactions.first else {
guard let result, case let .starsStatus(_, _, _, _, transactions, _, chats, users) = result, let matchingTransaction = transactions?.first else {
return nil
}
let peers = AccumulatedPeers(chats: chats, users: users)
@ -900,3 +1113,70 @@ func _internal_getStarsTransaction(accountPeerId: PeerId, postbox: Postbox, netw
}
}
}
public struct StarsSubscriptionPricing: Codable, Equatable {
private enum CodingKeys: String, CodingKey {
case period
case amount
}
public let period: Int32
public let amount: Int64
public init(period: Int32, amount: Int64) {
self.period = period
self.amount = amount
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.period = try container.decode(Int32.self, forKey: .period)
self.amount = try container.decode(Int64.self, forKey: .amount)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.period, forKey: .period)
try container.encode(self.amount, forKey: .amount)
}
public static let monthPeriod = 2592000
public static let testPeriod = 300
}
extension StarsSubscriptionPricing {
init(apiStarsSubscriptionPricing: Api.StarsSubscriptionPricing) {
switch apiStarsSubscriptionPricing {
case let .starsSubscriptionPricing(period, amount):
self = .init(period: period, amount: amount)
}
}
var apiStarsSubscriptionPricing: Api.StarsSubscriptionPricing {
return .starsSubscriptionPricing(period: self.period, amount: self.amount)
}
}
public enum CancelStarsSubsciptionError {
case generic
}
func _internal_cancelStarsSubscription(account: Account, subscriptionId: String, reason: String) -> Signal<Never, CancelStarsSubsciptionError> {
return account.postbox.transaction { transaction -> Api.InputPeer? in
return transaction.getPeer(account.peerId).flatMap(apiInputPeer)
}
|> castError(CancelStarsSubsciptionError.self)
|> mapToSignal { inputPeer -> Signal<Never, CancelStarsSubsciptionError> in
guard let inputPeer else {
return .complete()
}
let flags: Int32 = (1 << 0)
return account.network.request(Api.functions.payments.changeStarsSubscription(flags: flags, peer: inputPeer, subscriptionId: subscriptionId, canceled: .boolTrue))
|> mapError { _ -> CancelStarsSubsciptionError in
return .generic
}
|> ignoreValues
}
}

View File

@ -5,11 +5,11 @@ import Postbox
public extension TelegramEngine {
final class Payments {
private let account: Account
init(account: Account) {
self.account = account
}
public func getBankCardInfo(cardNumber: String) -> Signal<BankCardInfo?, NoError> {
return _internal_getBankCardInfo(account: self.account, cardNumber: cardNumber)
}
@ -25,7 +25,7 @@ public extension TelegramEngine {
public func validateBotPaymentForm(saveInfo: Bool, source: BotPaymentInvoiceSource, formInfo: BotPaymentRequestedInfo) -> Signal<BotPaymentValidatedFormInfo, ValidateBotPaymentFormError> {
return _internal_validateBotPaymentForm(account: self.account, saveInfo: saveInfo, source: source, formInfo: formInfo)
}
public func sendBotPaymentForm(source: BotPaymentInvoiceSource, formId: Int64, validatedInfoId: String?, shippingOptionId: String?, tipAmount: Int64?, credentials: BotPaymentCredentials) -> Signal<SendBotPaymentResult, SendBotPaymentFormError> {
return _internal_sendBotPaymentForm(account: self.account, formId: formId, source: source, validatedInfoId: validatedInfoId, shippingOptionId: shippingOptionId, tipAmount: tipAmount, credentials: credentials)
}
@ -33,7 +33,7 @@ public extension TelegramEngine {
public func requestBotPaymentReceipt(messageId: MessageId) -> Signal<BotPaymentReceipt, RequestBotPaymentReceiptError> {
return _internal_requestBotPaymentReceipt(account: self.account, messageId: messageId)
}
public func clearBotPaymentInfo(info: BotPaymentInfo) -> Signal<Void, NoError> {
return _internal_clearBotPaymentInfo(network: self.account.network, info: info)
}
@ -89,5 +89,9 @@ public extension TelegramEngine {
public func sendStarsPaymentForm(formId: Int64, source: BotPaymentInvoiceSource) -> Signal<SendBotPaymentResult, SendBotPaymentFormError> {
return _internal_sendStarsPaymentForm(account: self.account, formId: formId, source: source)
}
public func cancelStarsSubscription(subscriptionId: String, reason: String) -> Signal<Never, CancelStarsSubsciptionError> {
return _internal_cancelStarsSubscription(account: self.account, subscriptionId: subscriptionId, reason: reason)
}
}
}

View File

@ -44,7 +44,7 @@ func _internal_revokePersistentPeerExportedInvitation(account: Account, peerId:
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
let flags: Int32 = (1 << 2)
if let _ = peer as? TelegramChannel {
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil))
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil, subscriptionPricing: nil))
|> retryRequest
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
return account.postbox.transaction { transaction -> ExportedInvitation? in
@ -61,7 +61,7 @@ func _internal_revokePersistentPeerExportedInvitation(account: Account, peerId:
}
}
} else if let _ = peer as? TelegramGroup {
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil))
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: nil, usageLimit: nil, title: nil, subscriptionPricing: nil))
|> retryRequest
|> mapToSignal { result -> Signal<ExportedInvitation?, NoError> in
return account.postbox.transaction { transaction -> ExportedInvitation? in
@ -90,7 +90,7 @@ public enum CreatePeerExportedInvitationError {
case generic
}
func _internal_createPeerExportedInvitation(account: Account, peerId: PeerId, title: String?, expireDate: Int32?, usageLimit: Int32?, requestNeeded: Bool?) -> Signal<ExportedInvitation?, CreatePeerExportedInvitationError> {
func _internal_createPeerExportedInvitation(account: Account, peerId: PeerId, title: String?, expireDate: Int32?, usageLimit: Int32?, requestNeeded: Bool?, subscriptionPricing: StarsSubscriptionPricing?) -> Signal<ExportedInvitation?, CreatePeerExportedInvitationError> {
return account.postbox.transaction { transaction -> Signal<ExportedInvitation?, CreatePeerExportedInvitationError> in
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
var flags: Int32 = 0
@ -106,7 +106,10 @@ func _internal_createPeerExportedInvitation(account: Account, peerId: PeerId, ti
if let _ = title {
flags |= (1 << 4)
}
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: expireDate, usageLimit: usageLimit, title: title))
if let _ = subscriptionPricing {
flags |= (1 << 5)
}
return account.network.request(Api.functions.messages.exportChatInvite(flags: flags, peer: inputPeer, expireDate: expireDate, usageLimit: usageLimit, title: title, subscriptionPricing: subscriptionPricing?.apiStarsSubscriptionPricing))
|> mapError { _ in return CreatePeerExportedInvitationError.generic }
|> map { result -> ExportedInvitation? in
return ExportedInvitation(apiExportedInvite: result)
@ -817,7 +820,7 @@ private final class PeerInvitationImportersContextImpl {
var link: String?
var count: Int32 = 0
if let invite = invite, case let .link(inviteLink, _, _, _, _, _, _, _, _, _, inviteCount, _) = invite {
if let invite = invite, case let .link(inviteLink, _, _, _, _, _, _, _, _, _, inviteCount, _, _) = invite {
link = inviteLink
if let inviteCount = inviteCount {
count = inviteCount

View File

@ -48,6 +48,8 @@ public enum ExternalJoiningChatState {
public let participantsCount: Int32
public let participants: [EnginePeer]?
public let nameColor: PeerNameColor?
public let subscriptionPricing: StarsSubscriptionPricing?
public let subscriptionFormId: Int64?
}
case invite(Invite)
@ -106,10 +108,10 @@ func _internal_joinLinkInformation(_ hash: String, account: Account) -> Signal<E
|> mapToSignal { result -> Signal<ExternalJoiningChatState, JoinLinkInfoError> in
if let result = result {
switch result {
case let .chatInvite(flags, title, about, invitePhoto, participantsCount, participants, nameColor):
case let .chatInvite(flags, title, about, invitePhoto, participantsCount, participants, nameColor, subscriptionPricing, subscriptionFormId):
let photo = telegramMediaImageFromApiPhoto(invitePhoto).flatMap({ smallestImageRepresentation($0.representations) })
let flags: ExternalJoiningChatState.Invite.Flags = .init(isChannel: (flags & (1 << 0)) != 0, isBroadcast: (flags & (1 << 1)) != 0, isPublic: (flags & (1 << 2)) != 0, isMegagroup: (flags & (1 << 3)) != 0, requestNeeded: (flags & (1 << 6)) != 0, isVerified: (flags & (1 << 7)) != 0, isScam: (flags & (1 << 8)) != 0, isFake: (flags & (1 << 9)) != 0)
return .single(.invite(ExternalJoiningChatState.Invite(flags: flags, title: title, about: about, photoRepresentation: photo, participantsCount: participantsCount, participants: participants?.map({ EnginePeer(TelegramUser(user: $0)) }), nameColor: PeerNameColor(rawValue: nameColor))))
return .single(.invite(ExternalJoiningChatState.Invite(flags: flags, title: title, about: about, photoRepresentation: photo, participantsCount: participantsCount, participants: participants?.map({ EnginePeer(TelegramUser(user: $0)) }), nameColor: PeerNameColor(rawValue: nameColor), subscriptionPricing: subscriptionPricing.flatMap { StarsSubscriptionPricing(apiStarsSubscriptionPricing: $0) }, subscriptionFormId: subscriptionFormId)))
case let .chatInviteAlready(chat):
if let peer = parseTelegramGroupOrChannel(chat: chat) {
return account.postbox.transaction({ (transaction) -> ExternalJoiningChatState in

View File

@ -705,8 +705,8 @@ public extension TelegramEngine {
return _internal_checkPeerChatServiceActions(postbox: self.account.postbox, peerId: peerId)
}
public func createPeerExportedInvitation(peerId: PeerId, title: String?, expireDate: Int32?, usageLimit: Int32?, requestNeeded: Bool?) -> Signal<ExportedInvitation?, CreatePeerExportedInvitationError> {
return _internal_createPeerExportedInvitation(account: self.account, peerId: peerId, title: title, expireDate: expireDate, usageLimit: usageLimit, requestNeeded: requestNeeded)
public func createPeerExportedInvitation(peerId: PeerId, title: String?, expireDate: Int32?, usageLimit: Int32?, requestNeeded: Bool?, subscriptionPricing: StarsSubscriptionPricing?) -> Signal<ExportedInvitation?, CreatePeerExportedInvitationError> {
return _internal_createPeerExportedInvitation(account: self.account, peerId: peerId, title: title, expireDate: expireDate, usageLimit: usageLimit, requestNeeded: requestNeeded, subscriptionPricing: subscriptionPricing)
}
public func editPeerExportedInvitation(peerId: PeerId, link: String, title: String?, expireDate: Int32?, usageLimit: Int32?, requestNeeded: Bool?) -> Signal<ExportedInvitation?, EditPeerExportedInvitationError> {

View File

@ -1460,7 +1460,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
var text: String = ""
var entities: [MessageTextEntity] = []
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_DeletedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link_?.replacingOccurrences(of: "https://", with: "") ?? "")
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_DeletedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "")
appendAttributedText(text: rawText, generateEntities: { index in
if index == 0, let author = author {
@ -1486,7 +1486,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
var text: String = ""
var entities: [MessageTextEntity] = []
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_RevokedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link_?.replacingOccurrences(of: "https://", with: "") ?? "")
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_RevokedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "")
appendAttributedText(text: rawText, generateEntities: { index in
if index == 0, let author = author {
@ -1512,7 +1512,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
var text: String = ""
var entities: [MessageTextEntity] = []
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_EditedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", updatedInvite.link_?.replacingOccurrences(of: "https://", with: "") ?? "")
let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_EditedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", updatedInvite.link?.replacingOccurrences(of: "https://", with: "") ?? "")
appendAttributedText(text: rawText, generateEntities: { index in
if index == 0, let author = author {
@ -1540,9 +1540,9 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
let rawText: PresentationStrings.FormattedString
if joinedViaFolderLink {
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaFolderInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link_?.replacingOccurrences(of: "https://", with: "") ?? "")
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaFolderInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "")
} else {
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link_?.replacingOccurrences(of: "https://", with: "") ?? "")
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "")
}
appendAttributedText(text: rawText, generateEntities: { index in
@ -1709,7 +1709,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
let rawText: PresentationStrings.FormattedString
switch invite {
case let .link(link, _, _, _, _, _, _, _, _, _, _, _):
case let .link(link, _, _, _, _, _, _, _, _, _, _, _, _):
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaRequest(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", link.replacingOccurrences(of: "https://", with: ""), approver.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
case .publicJoinRequest:
rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaPublicRequest(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", approver.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
@ -2326,14 +2326,3 @@ func chatRecentActionsHistoryPreparedTransition(from fromEntries: [ChatRecentAct
return ChatRecentActionsHistoryTransition(filteredEntries: toEntries, type: type, deletions: deletions, insertions: insertions, updates: updates, canLoadEarlier: canLoadEarlier, displayingResults: displayingResults, searchResultsState: searchResultsState, synchronous: !toggledDeletedMessageIds.isEmpty, isEmpty: toEntries.isEmpty)
}
private extension ExportedInvitation {
var link_: String? {
switch self {
case let .link(link, _, _, _, _, _, _, _, _, _, _, _):
return link
case .publicJoinRequest:
return nil
}
}
}