Various improvements

This commit is contained in:
Ilya Laktyushin 2022-06-11 15:55:01 +04:00
parent eaf6a69cfb
commit 0788e34625
4 changed files with 121 additions and 96 deletions

View File

@ -219,36 +219,22 @@ private func getReceiptData() -> Data? {
extension InAppPurchaseManager: SKPaymentTransactionObserver {
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
self.stateQueue.async {
let accountPeerId = "\(self.engine.account.peerId.toInt64())"
if let applicationUsername = transaction.payment.applicationUsername, applicationUsername != accountPeerId {
continue
}
let productIdentifier = transaction.payment.productIdentifier
self.stateQueue.async {
var transactionsToAssign: [SKPaymentTransaction] = []
for transaction in transactions {
if let applicationUsername = transaction.payment.applicationUsername, applicationUsername != accountPeerId {
continue
}
let productIdentifier = transaction.payment.productIdentifier
let transactionState: TransactionState?
switch transaction.transactionState {
case .purchased:
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transaction \(transaction.transactionIdentifier ?? ""), original transaction \(transaction.original?.transactionIdentifier ?? "none") purchased")
let transactionIdentifier = transaction.transactionIdentifier
transactionState = .purchased(transactionId: transactionIdentifier)
if let transactionIdentifier = transactionIdentifier {
self.disposableSet.set(
self.engine.payments.sendAppStoreReceipt(receipt: getReceiptData() ?? Data(), restore: false).start(error: { [weak self] _ in
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transaction \(transaction.transactionIdentifier ?? "") failed to assign AppStore transaction")
queue.finishTransaction(transaction)
if let strongSelf = self, let context = strongSelf.paymentContexts[productIdentifier] {
context.subscriber(.assignFailed)
}
}, completed: {
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transaction \(transaction.transactionIdentifier ?? "") successfully assigned AppStore transaction")
queue.finishTransaction(transaction)
}),
forKey: transactionIdentifier
)
}
transactionState = .purchased(transactionId: transaction.transactionIdentifier)
transactionsToAssign.append(transaction)
case .restored:
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transaction \(transaction.transactionIdentifier ?? ""), original transaction \(transaction.original?.transactionIdentifier ?? "") restroring")
let transactionIdentifier = transaction.transactionIdentifier
@ -272,6 +258,31 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver {
}
}
}
if !transactionsToAssign.isEmpty {
let transactionIds = transactionsToAssign.compactMap({ $0.transactionIdentifier }).joined(separator: ", ")
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), sending receipt for transactions [\(transactionIds)]")
self.disposableSet.set(
self.engine.payments.sendAppStoreReceipt(receipt: getReceiptData() ?? Data(), restore: false).start(error: { [weak self] _ in
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transactions [\(transactionIds)] failed to assign")
for transaction in transactions {
self?.stateQueue.async {
if let strongSelf = self, let context = strongSelf.paymentContexts[transaction.payment.productIdentifier] {
context.subscriber(.assignFailed)
}
}
queue.finishTransaction(transaction)
}
}, completed: {
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transactions [\(transactionIds)] successfully assigned")
for transaction in transactions {
queue.finishTransaction(transaction)
}
}),
forKey: transactionIds
)
}
}
}

View File

@ -1422,16 +1422,23 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
return .never()
}
|> timeout(15.0, queue: Queue.mainQueue(), alternate: .fail(.timeout))
|> deliverOnMainQueue).start(error: { _ in
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail")
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let errorText = presentationData.strings.Premium_Purchase_ErrorUnknown
let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
strongSelf.present(alertController)
|> deliverOnMainQueue).start(error: { [weak self] _ in
if let strongSelf = self {
strongSelf.inProgress = false
strongSelf.updated(transition: .immediate)
strongSelf.completion()
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail")
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let errorText = presentationData.strings.Premium_Purchase_ErrorUnknown
let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
strongSelf.present(alertController)
}
}, completed: { [weak self] in
if let strongSelf = self {
let _ = updatePremiumPromoConfigurationOnce(account: strongSelf.context.account).start()
strongSelf.inProgress = false
strongSelf.isPremium = true
strongSelf.updated(transition: .easeInOut(duration: 0.25))
strongSelf.completion()

View File

@ -851,23 +851,24 @@ private final class LimitSheetContent: CombinedComponent {
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height),
transition: .immediate
)
let gradientColors: [UIColor]
if isPremiumDisabled {
gradientColors = [
UIColor(rgb: 0x007afe),
UIColor(rgb: 0x5494ff)
]
} else {
gradientColors = [
UIColor(rgb: 0x0077ff),
UIColor(rgb: 0x6b93ff),
UIColor(rgb: 0x8878ff),
UIColor(rgb: 0xe46ace)
]
}
let contentSize: CGSize
if state.initialized {
let gradientColors: [UIColor]
if isPremiumDisabled {
gradientColors = [
UIColor(rgb: 0x007afe),
UIColor(rgb: 0x5494ff)
]
} else {
gradientColors = [
UIColor(rgb: 0x0077ff),
UIColor(rgb: 0x6b93ff),
UIColor(rgb: 0x8878ff),
UIColor(rgb: 0xe46ace)
]
}
let limit = limit.update(
component: PremiumLimitDisplayComponent(
inactiveColor: theme.list.itemBlocksSeparatorColor.withAlphaComponent(0.5),
@ -889,58 +890,60 @@ private final class LimitSheetContent: CombinedComponent {
context.add(limit
.position(CGPoint(x: context.availableSize.width / 2.0, y: limit.size.height / 2.0 + 44.0))
)
}
let isIncreaseButton = !reachedMaximumLimit && !isPremiumDisabled
let button = button.update(
component: SolidRoundedButtonComponent(
title: isIncreaseButton ? strings.Premium_IncreaseLimit : strings.Common_OK,
theme: SolidRoundedButtonComponent.Theme(
backgroundColor: .black,
backgroundColors: gradientColors,
foregroundColor: .white
let isIncreaseButton = !reachedMaximumLimit && !isPremiumDisabled
let button = button.update(
component: SolidRoundedButtonComponent(
title: isIncreaseButton ? strings.Premium_IncreaseLimit : strings.Common_OK,
theme: SolidRoundedButtonComponent.Theme(
backgroundColor: .black,
backgroundColors: gradientColors,
foregroundColor: .white
),
font: .bold,
fontSize: 17.0,
height: 50.0,
cornerRadius: 10.0,
gloss: isIncreaseButton,
animationName: isIncreaseButton ? buttonAnimationName : nil,
iconPosition: .right,
action: { [weak component] in
guard let component = component else {
return
}
component.dismiss()
if isIncreaseButton {
component.action()
}
}
),
font: .bold,
fontSize: 17.0,
height: 50.0,
cornerRadius: 10.0,
gloss: isIncreaseButton,
animationName: isIncreaseButton ? buttonAnimationName : nil,
iconPosition: .right,
action: { [weak component] in
guard let component = component else {
return
}
component.dismiss()
if isIncreaseButton {
component.action()
}
}
),
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
transition: context.transition
)
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 50.0),
transition: context.transition
)
var textOffset: CGFloat = 228.0
if isPremiumDisabled {
textOffset -= 68.0
}
context.add(title
.position(CGPoint(x: context.availableSize.width / 2.0, y: 28.0))
)
context.add(text
.position(CGPoint(x: context.availableSize.width / 2.0, y: textOffset))
)
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: textOffset + ceil(text.size.height / 2.0) + 38.0), size: button.size)
context.add(button
.position(CGPoint(x: buttonFrame.midX, y: buttonFrame.midY))
)
var textOffset: CGFloat = 228.0
if isPremiumDisabled {
textOffset -= 68.0
contentSize = CGSize(width: context.availableSize.width, height: buttonFrame.maxY + 5.0 + environment.safeInsets.bottom)
} else {
contentSize = CGSize(width: context.availableSize.width, height: 351.0 + environment.safeInsets.bottom)
}
context.add(title
.position(CGPoint(x: context.availableSize.width / 2.0, y: 28.0))
)
context.add(text
.position(CGPoint(x: context.availableSize.width / 2.0, y: textOffset))
)
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: textOffset + ceil(text.size.height / 2.0) + 38.0), size: button.size)
context.add(button
.position(CGPoint(x: buttonFrame.midX, y: buttonFrame.midY))
)
let contentSize = CGSize(width: context.availableSize.width, height: buttonFrame.maxY + 5.0 + environment.safeInsets.bottom)
return contentSize
}
}

View File

@ -808,6 +808,10 @@ public final class SolidRoundedButtonView: UIView {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.animationTimer?.invalidate()
}
private func setupGloss() {
if self.gloss {
if self.shimmerView == nil {
@ -1002,7 +1006,7 @@ public final class SolidRoundedButtonView: UIView {
compositingFilter = nil
}
let globalTimeOffset = self.icon == nil
let globalTimeOffset = self.icon == nil && self.animation == nil
shimmerView.update(backgroundColor: .clear, foregroundColor: color.withAlphaComponent(alpha), gradientSize: 70.0, globalTimeOffset: globalTimeOffset, duration: 3.0, horizontal: true)
borderShimmerView.update(backgroundColor: .clear, foregroundColor: color.withAlphaComponent(borderAlpha), gradientSize: 70.0, globalTimeOffset: globalTimeOffset, duration: 3.0, horizontal: true)