mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Paid media improvements
This commit is contained in:
parent
d02046973f
commit
9fe5a800e9
@ -12383,6 +12383,7 @@ Sorry for the inconvenience.";
|
||||
"Stars.PaidContent.AmountTitle" = "ENTER UNLOCK COST";
|
||||
"Stars.PaidContent.AmountPlaceholder" = "Stars to Unlock";
|
||||
"Stars.PaidContent.AmountInfo" = "Users will have to transfer this amount of Stars to your channel in order to view this media.\n[More about Stars >]()";
|
||||
"Stars.PaidContent.AmountInfo_URL" = "https://telegram.org";
|
||||
"Stars.PaidContent.Create" = "Make This Media Paid";
|
||||
|
||||
"MediaEditor.AddLink" = "LINK";
|
||||
@ -12420,7 +12421,7 @@ Sorry for the inconvenience.";
|
||||
"Monetization.BalanceStarsWithdraw" = "Withdraw via Fragment";
|
||||
"Monetization.BalanceStarsWithdrawShort" = "Withdraw";
|
||||
"Monetization.BalanceStarsBuyAds" = "Buy Ads";
|
||||
"Monetization.Balance.StarsInfo" = "You can withdraw Stars using Fragment, or use Stars to advertise your channel. [Learn More >]()";
|
||||
"Monetization.Balance.StarsInfo" = "You can collect rewards for Stars using Fragment, or use Stars to advertise your channel. [Learn More >]()";
|
||||
"Monetization.Balance.StarsInfo_URL" = "https://telegram.org";
|
||||
|
||||
"Monetization.StarsProceeds.Title" = "Rewards Overview";
|
||||
|
@ -0,0 +1,40 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
private func _internal_updateExtendedMediaById(account: Account, peerId: EnginePeer.Id, messageIds: [EngineMessage.Id]) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Peer? in
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
return peer
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> mapToSignal { peer -> Signal<Never, NoError> in
|
||||
guard let peer = peer, let inputPeer = apiInputPeer(peer) else {
|
||||
return .complete()
|
||||
}
|
||||
return account.network.request(Api.functions.messages.getExtendedMedia(peer: inputPeer, id: messageIds.map { $0.id }))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Never, NoError> in
|
||||
if let updates = updates {
|
||||
account.stateManager.addUpdates(updates)
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_updateExtendedMedia(account: Account, messageIds: [EngineMessage.Id]) -> Signal<Never, NoError> {
|
||||
var signals: [Signal<Never, NoError>] = []
|
||||
for (peerId, messageIds) in messagesIdsGroupedByPeerId(messageIds) {
|
||||
signals.append(_internal_updateExtendedMediaById(account: account, peerId: peerId, messageIds: messageIds))
|
||||
}
|
||||
return combineLatest(signals)
|
||||
|> ignoreValues
|
||||
}
|
@ -1431,6 +1431,10 @@ public extension TelegramEngine {
|
||||
return _internal_reportAdMessage(account: self.account, peerId: peerId, opaqueId: opaqueId, option: option)
|
||||
}
|
||||
|
||||
public func updateExtendedMedia(messageIds: [EngineMessage.Id]) -> Signal<Never, NoError> {
|
||||
return _internal_updateExtendedMedia(account: self.account, messageIds: messageIds)
|
||||
}
|
||||
|
||||
public func getAllLocalChannels(count: Int) -> Signal<[EnginePeer.Id], NoError> {
|
||||
return self.account.postbox.transaction { transaction -> [EnginePeer.Id] in
|
||||
var result: [EnginePeer.Id] = []
|
||||
|
@ -756,6 +756,8 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
||||
return .fail(.paymentFailed)
|
||||
} else if error.errorDescription == "INVOICE_ALREADY_PAID" {
|
||||
return .fail(.alreadyPaid)
|
||||
} else if error.errorDescription == "MEDIA_ALREADY_PAID" {
|
||||
return .fail(.alreadyPaid)
|
||||
}
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ private final class SheetContent: CombinedComponent {
|
||||
private let context: AccountContext
|
||||
private let starsContext: StarsContext
|
||||
private let source: BotPaymentInvoiceSource
|
||||
private let extendedMedia: [TelegramExtendedMedia]
|
||||
private let invoice: TelegramMediaInvoice
|
||||
|
||||
private(set) var botPeer: EnginePeer?
|
||||
@ -92,12 +93,14 @@ private final class SheetContent: CombinedComponent {
|
||||
context: AccountContext,
|
||||
starsContext: StarsContext,
|
||||
source: BotPaymentInvoiceSource,
|
||||
extendedMedia: [TelegramExtendedMedia],
|
||||
invoice: TelegramMediaInvoice,
|
||||
inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>
|
||||
) {
|
||||
self.context = context
|
||||
self.starsContext = starsContext
|
||||
self.source = source
|
||||
self.extendedMedia = extendedMedia
|
||||
self.invoice = invoice
|
||||
|
||||
super.init()
|
||||
@ -150,7 +153,7 @@ private final class SheetContent: CombinedComponent {
|
||||
self.optionsDisposable?.dispose()
|
||||
}
|
||||
|
||||
func buy(requestTopUp: @escaping (@escaping () -> Void) -> Void, completion: @escaping () -> Void) {
|
||||
func buy(requestTopUp: @escaping (@escaping () -> Void) -> Void, completion: @escaping (Bool) -> Void) {
|
||||
guard let form, let balance else {
|
||||
return
|
||||
}
|
||||
@ -164,7 +167,20 @@ private final class SheetContent: CombinedComponent {
|
||||
|
||||
let _ = (self.context.engine.payments.sendStarsPaymentForm(formId: form.id, source: self.source)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
completion()
|
||||
completion(true)
|
||||
}, error: { [weak self] error in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
switch error {
|
||||
case .alreadyPaid:
|
||||
if !self.extendedMedia.isEmpty, case let .message(messageId) = self.source {
|
||||
let _ = self.context.engine.messages.updateExtendedMedia(messageIds: [messageId]).startStandalone()
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
completion(false)
|
||||
})
|
||||
}
|
||||
|
||||
@ -209,7 +225,7 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
|
||||
func makeState() -> State {
|
||||
return State(context: self.context, starsContext: self.starsContext, source: self.source, invoice: self.invoice, inputData: self.inputData)
|
||||
return State(context: self.context, starsContext: self.starsContext, source: self.source, extendedMedia: self.extendedMedia, invoice: self.invoice, inputData: self.inputData)
|
||||
}
|
||||
|
||||
static var body: Body {
|
||||
@ -481,37 +497,38 @@ private final class SheetContent: CombinedComponent {
|
||||
let alertController = textAlertController(context: accountContext, title: nil, text: presentationData.strings.Stars_Transfer_Unavailable, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||
controller?.present(alertController, in: .window(.root))
|
||||
}
|
||||
}, completion: { [weak controller] in
|
||||
let presentationData = accountContext.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let text: String
|
||||
if let _ = component.invoice.extendedMedia {
|
||||
text = presentationData.strings.Stars_Transfer_UnlockedText( presentationData.strings.Stars_Transfer_Purchased_Stars(Int32(invoice.totalAmount))).string
|
||||
} else {
|
||||
text = presentationData.strings.Stars_Transfer_PurchasedText(invoice.title, botTitle, presentationData.strings.Stars_Transfer_Purchased_Stars(Int32(invoice.totalAmount))).string
|
||||
}
|
||||
|
||||
if let navigationController = controller?.navigationController {
|
||||
Queue.mainQueue().after(0.5) {
|
||||
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .image(
|
||||
image: UIImage(bundleImageName: "Premium/Stars/StarLarge")!,
|
||||
title: presentationData.strings.Stars_Transfer_PurchasedTitle,
|
||||
text: text,
|
||||
round: false,
|
||||
undoText: nil
|
||||
),
|
||||
elevatedLayout: lastController is ChatController,
|
||||
action: { _ in return true}
|
||||
)
|
||||
lastController.present(resultController, in: .window(.root))
|
||||
}, completion: { [weak controller] success in
|
||||
if success {
|
||||
let presentationData = accountContext.sharedContext.currentPresentationData.with { $0 }
|
||||
let text: String
|
||||
if let _ = component.invoice.extendedMedia {
|
||||
text = presentationData.strings.Stars_Transfer_UnlockedText( presentationData.strings.Stars_Transfer_Purchased_Stars(Int32(invoice.totalAmount))).string
|
||||
} else {
|
||||
text = presentationData.strings.Stars_Transfer_PurchasedText(invoice.title, botTitle, presentationData.strings.Stars_Transfer_Purchased_Stars(Int32(invoice.totalAmount))).string
|
||||
}
|
||||
|
||||
if let navigationController = controller?.navigationController {
|
||||
Queue.mainQueue().after(0.5) {
|
||||
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||
let resultController = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .image(
|
||||
image: UIImage(bundleImageName: "Premium/Stars/StarLarge")!,
|
||||
title: presentationData.strings.Stars_Transfer_PurchasedTitle,
|
||||
text: text,
|
||||
round: false,
|
||||
undoText: nil
|
||||
),
|
||||
elevatedLayout: lastController is ChatController,
|
||||
action: { _ in return true}
|
||||
)
|
||||
lastController.present(resultController, in: .window(.root))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
controller?.complete(paid: true)
|
||||
controller?.complete(paid: success)
|
||||
controller?.dismissAnimated()
|
||||
|
||||
starsContext.load(force: true)
|
||||
|
@ -67,6 +67,7 @@ private final class SheetContent: CombinedComponent {
|
||||
let state = context.state
|
||||
|
||||
let theme = environment.theme.withModalBlocksBackground()
|
||||
let strings = environment.strings
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
@ -200,7 +201,18 @@ private final class SheetContent: CombinedComponent {
|
||||
}
|
||||
amountFooter = AnyComponent(MultilineTextComponent(
|
||||
text: .plain(amountInfoString),
|
||||
maximumNumberOfLines: 0
|
||||
maximumNumberOfLines: 0,
|
||||
highlightColor: environment.theme.list.itemAccentColor.withAlphaComponent(0.2),
|
||||
highlightAction: { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
||||
return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
tapAction: { attributes, _ in
|
||||
component.context.sharedContext.openExternalUrl(context: component.context, urlContext: .generic, url: strings.Stars_PaidContent_AmountInfo_URL, forceExternal: true, presentationData: presentationData, navigationController: nil, dismissInput: {})
|
||||
}
|
||||
))
|
||||
} else {
|
||||
amountFooter = nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user