diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 11e50be953..b01cdd2105 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7653,8 +7653,6 @@ Sorry for the inconvenience."; "Premium.Terms" = "By purchasing a Premium subscription, you agree to our [Terms of Service](terms) and [Privacy Policy](privacy)."; -"Premium.ChargeInfo" = "Next charge: %1$@ on %2$@. [Cancel](cancel)."; - "Conversation.CopyProtectionSavingDisabledSecret" = "Saving is restricted"; "Conversation.CopyProtectionForwardingDisabledSecret" = "Forwards are restricted"; @@ -7668,8 +7666,6 @@ Sorry for the inconvenience."; "SponsoredMessageMenu.Hide" = "Hide"; -"ChatListFolder.MaxChatsInFolder" = "Sorry, you can't add more than %d chats to a folder."; - "Conversation.SaveGif" = "Save GIF"; "Premium.Limits.Title" = "Doubled Limits"; @@ -7705,3 +7701,7 @@ Sorry for the inconvenience."; "Message.AudioTranscription.ErrorTooLong" = "The audio is too long"; "WebApp.SelectChat" = "Select Chat"; + +"Premium.Purchase.ErrorUnknown" = "An error occurred. Please try again."; +"Premium.Purchase.ErrorNetwork" = "Please check your internet connection and try again."; +"Premium.Purchase.ErrorNotAllowed" = "The device is not not allowed to make the payment."; diff --git a/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift b/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift index 96799af2dd..367bbdd972 100644 --- a/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift +++ b/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift @@ -28,6 +28,8 @@ public final class InAppPurchaseManager: NSObject { public enum PurchaseError { case generic case cancelled + case network + case notAllowed } private final class PaymentTransactionContext { @@ -43,7 +45,7 @@ public final class InAppPurchaseManager: NSObject { case purchased(transactionId: String?) case restored(transactionId: String?) case purchasing - case failed + case failed(error: SKError?) case deferred } @@ -109,8 +111,23 @@ public final class InAppPurchaseManager: NSObject { } else { subscriber.putError(.generic) } - case .failed: - subscriber.putError(.generic) + case let .failed(error): + if let error = error { + let mappedError: PurchaseError + switch error.code { + case .paymentCancelled: + mappedError = .cancelled + case .cloudServiceNetworkConnectionFailed, .cloudServicePermissionDenied: + mappedError = .network + case .paymentNotAllowed, .clientInvalid: + mappedError = .notAllowed + default: + mappedError = .generic + } + subscriber.putError(mappedError) + } else { + subscriber.putError(.generic) + } case .deferred, .purchasing: break } @@ -174,7 +191,7 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver { ) } case .failed: - transactionState = .failed + transactionState = .failed(error: transaction.error as? SKError) queue.finishTransaction(transaction) case .purchasing: transactionState = .purchasing diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index 1673f25a0c..943ddb8b95 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -894,7 +894,7 @@ private final class DemoSheetContent: CombinedComponent { font: .bold, fontSize: 17.0, height: 50.0, - cornerRadius: 10.0, + cornerRadius: 11.0, gloss: state.isPremium != true, animationName: isStandalone && component.subject == .uniqueReactions ? "premium_unlock" : nil, iconPosition: .right, diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 9779dee9ac..b443345f23 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -1404,12 +1404,25 @@ private final class PremiumIntroScreenComponent: CombinedComponent { strongSelf.updateInProgress(false) strongSelf.updated(transition: .immediate) + let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } + var errorText: String? switch error { case .generic: - addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail") + errorText = presentationData.strings.Premium_Purchase_ErrorUnknown + case .network: + errorText = presentationData.strings.Premium_Purchase_ErrorNetwork + case .notAllowed: + errorText = presentationData.strings.Premium_Purchase_ErrorNotAllowed case .cancelled: break } + + if let errorText = errorText { + addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail") + + let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) + strongSelf.present(alertController) + } } })) } else { @@ -1635,7 +1648,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { foregroundColor: .white ), height: 50.0, - cornerRadius: 10.0, + cornerRadius: 11.0, gloss: true, isLoading: state.inProgress, action: { diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index 3b419a7a16..0d35423853 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -388,7 +388,7 @@ private final class PremimLimitsListScreenComponent: CombinedComponent { .position(CGPoint(x: context.availableSize.width / 2.0, y: environment.navigationHeight + list.size.height / 2.0)) ) - return CGSize(width: context.availableSize.width, height: environment.navigationHeight + list.size.height + environment.safeInsets.bottom - 16.0) + return CGSize(width: context.availableSize.width, height: environment.navigationHeight + list.size.height + environment.safeInsets.bottom) } } } @@ -492,7 +492,7 @@ public class PremimLimitsListScreen: ViewController { let contentOffset = self.scrollView.contentOffset.y self.controller?.navigationBar?.updateBackgroundAlpha(min(30.0, contentOffset) / 30.0, transition: .immediate) - let bottomOffsetY = max(0.0, self.scrollView.contentSize.height + 20.0 - contentOffset - self.scrollView.frame.height) + let bottomOffsetY = max(0.0, self.scrollView.contentSize.height - contentOffset - self.scrollView.frame.height) let backgroundAlpha: CGFloat = min(30.0, bottomOffsetY) / 30.0 self.footerNode.updateBackgroundAlpha(backgroundAlpha, transition: .immediate) @@ -1077,28 +1077,19 @@ private class FooterNode: ASDisplayNode { let buttonInset: CGFloat = 16.0 let buttonWidth = layout.size.width - layout.safeInsets.left - layout.safeInsets.right - buttonInset * 2.0 let buttonHeight = self.buttonNode.updateLayout(width: buttonWidth, transition: transition) - let inset: CGFloat = 9.0 - - let insets = layout.insets(options: [.input]) - - var panelHeight: CGFloat = buttonHeight + inset * 2.0 - let totalPanelHeight: CGFloat - if let inputHeight = layout.inputHeight, inputHeight > 0.0 { - totalPanelHeight = panelHeight + insets.bottom - } else { - panelHeight += insets.bottom - totalPanelHeight = panelHeight - } - + let bottomPanelPadding: CGFloat = 12.0 + let bottomInset: CGFloat = layout.intrinsicInsets.bottom > 0.0 ? layout.intrinsicInsets.bottom + 5.0 : bottomPanelPadding + + let panelHeight: CGFloat = bottomPanelPadding + 50.0 + bottomInset let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: panelHeight)) - transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + buttonInset, y: panelFrame.minY + inset), size: CGSize(width: buttonWidth, height: buttonHeight))) + transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: CGPoint(x: layout.safeInsets.left + buttonInset, y: bottomPanelPadding), size: CGSize(width: buttonWidth, height: buttonHeight))) transition.updateFrame(node: self.backgroundNode, frame: panelFrame) self.backgroundNode.update(size: panelFrame.size, transition: transition) - transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: panelFrame.origin, size: CGSize(width: panelFrame.width, height: UIScreenPixel))) + transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: panelFrame.width, height: UIScreenPixel))) - return totalPanelHeight + return panelHeight } override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { diff --git a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift index 2d6ee14a8c..9fd0484b47 100644 --- a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift +++ b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift @@ -649,6 +649,9 @@ public final class SolidRoundedButtonView: UIView { self.buttonBackgroundNode = UIImageView() self.buttonBackgroundNode.clipsToBounds = true self.buttonBackgroundNode.layer.cornerRadius = cornerRadius + if #available(iOS 13.0, *) { + self.buttonBackgroundNode.layer.cornerCurve = .continuous + } self.buttonBackgroundNode.backgroundColor = theme.backgroundColor if theme.backgroundColors.count > 1 {