Various improvements

This commit is contained in:
Ilya Laktyushin 2022-05-26 03:05:10 +04:00
parent 690045cf99
commit f7ec8a0bf2
3 changed files with 65 additions and 12 deletions

View File

@ -27,6 +27,7 @@ public final class InAppPurchaseManager: NSObject {
public enum PurchaseError {
case generic
case cancelled
}
private final class PaymentTransactionContext {

View File

@ -19,7 +19,7 @@ import ConfettiEffect
import TextFormat
import InstantPageCache
public enum PremiumSource {
public enum PremiumSource: Equatable {
case settings
case stickers
case reactions
@ -33,6 +33,7 @@ public enum PremiumSource {
case folders
case chatsPerFolder
case accounts
case deeplink(String?)
var identifier: String {
switch self {
@ -62,6 +63,12 @@ public enum PremiumSource {
return "double_limits__dialog_filters_chats"
case .accounts:
return "double_limits__accounts"
case let .deeplink(reference):
if let reference = reference {
return "deeplink_\(reference)"
} else {
return "deeplink"
}
}
}
}
@ -718,14 +725,16 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
typealias EnvironmentType = (ViewControllerComponentContainer.Environment, ScrollChildEnvironment)
let context: AccountContext
let source: PremiumSource
let isPremium: Bool?
let price: String?
let present: (ViewController) -> Void
let buy: () -> Void
let updateIsFocused: (Bool) -> Void
init(context: AccountContext, isPremium: Bool?, price: String?, present: @escaping (ViewController) -> Void, buy: @escaping () -> Void, updateIsFocused: @escaping (Bool) -> Void) {
init(context: AccountContext, source: PremiumSource, isPremium: Bool?, price: String?, present: @escaping (ViewController) -> Void, buy: @escaping () -> Void, updateIsFocused: @escaping (Bool) -> Void) {
self.context = context
self.source = source
self.isPremium = isPremium
self.price = price
self.present = present
@ -737,6 +746,9 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
if lhs.context !== rhs.context {
return false
}
if lhs.source != rhs.source {
return false
}
if lhs.isPremium != rhs.isPremium {
return false
}
@ -749,11 +761,13 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
final class State: ComponentState {
private let context: AccountContext
var price: String?
private var disposable: Disposable?
var configuration = PremiumIntroConfiguration.defaultValue
private(set) var configuration = PremiumIntroConfiguration.defaultValue
init(context: AccountContext) {
init(context: AccountContext, source: PremiumSource) {
self.context = context
super.init()
@ -768,6 +782,25 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
if let strongSelf = self {
strongSelf.configuration = PremiumIntroConfiguration.with(appConfiguration: appConfiguration)
strongSelf.updated(transition: .immediate)
var jsonString: String = "{"
jsonString += "\"source\": \"\(source.identifier)\","
jsonString += "\"data\": {\"premium_promo_order\":["
var isFirst = true
for perk in strongSelf.configuration.perks {
if !isFirst {
jsonString += ","
}
isFirst = false
jsonString += "\"\(perk.identifier)\""
}
jsonString += "]}}"
if let data = jsonString.data(using: .utf8), let json = JSON(data: data) {
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_show", data: json)
}
}
})
}
@ -778,7 +811,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
}
func makeState() -> State {
return State(context: self.context)
return State(context: self.context, source: self.source)
}
static var body: Body {
@ -797,6 +830,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
let scrollEnvironment = context.environment[ScrollChildEnvironment.self].value
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
let state = context.state
state.price = context.component.price
let theme = environment.theme
let strings = environment.strings
@ -882,7 +916,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
let present = context.component.present
let buy = context.component.buy
let updateIsFocused = context.component.updateIsFocused
let price = context.component.price
var i = 0
for perk in state.configuration.perks {
let iconBackgroundColors = gradientColors[i]
@ -904,7 +938,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
)
)
),
action: {
action: { [weak state] in
var demoSubject: PremiumDemoScreen.Subject
switch perk {
case .doubleLimits:
@ -933,7 +967,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
let controller = PremiumDemoScreen(
context: accountContext,
subject: demoSubject,
source: .intro(price),
source: .intro(state?.price),
action: {
dismissImpl?()
buy()
@ -947,6 +981,8 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
controller?.dismiss(animated: true, completion: nil)
}
updateIsFocused(true)
addAppLogEvent(postbox: accountContext.account.postbox, type: "premium.promo_screen_tap", data: ["item": perk.identifier])
}
))
i += 1
@ -1141,12 +1177,14 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext
let source: PremiumSource
let updateInProgress: (Bool) -> Void
let present: (ViewController) -> Void
let completion: () -> Void
init(context: AccountContext, updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, completion: @escaping () -> Void) {
init(context: AccountContext, source: PremiumSource, updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, completion: @escaping () -> Void) {
self.context = context
self.source = source
self.updateInProgress = updateInProgress
self.present = present
self.completion = completion
@ -1156,6 +1194,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
if lhs.context !== rhs.context {
return false
}
if lhs.source != rhs.source {
return false
}
return true
}
@ -1214,6 +1255,8 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
return
}
addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept")
self.inProgress = true
self.updateInProgress(true)
self.updated(transition: .immediate)
@ -1230,11 +1273,18 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
}
}))
}
}, error: { [weak self] _ in
}, error: { [weak self] error in
if let strongSelf = self {
strongSelf.inProgress = false
strongSelf.updateInProgress(false)
strongSelf.updated(transition: .immediate)
switch error {
case .generic:
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail")
case .cancelled:
break
}
}
}))
}
@ -1350,6 +1400,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
component: ScrollComponent<EnvironmentType>(
content: AnyComponent(PremiumIntroScreenContentComponent(
context: context.component.context,
source: context.component.source,
isPremium: state.isPremium,
price: state.premiumProduct?.price,
present: context.component.present,
@ -1459,7 +1510,7 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer {
return self._ready
}
public init(context: AccountContext, modal: Bool = true, reference: String? = nil, source: PremiumSource? = nil) {
public init(context: AccountContext, modal: Bool = true, source: PremiumSource) {
self.context = context
var updateInProgressImpl: ((Bool) -> Void)?
@ -1467,6 +1518,7 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer {
var completionImpl: (() -> Void)?
super.init(context: context, component: PremiumIntroScreenComponent(
context: context,
source: source,
updateInProgress: { inProgress in
updateInProgressImpl?(inProgress)
},

View File

@ -522,7 +522,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|> deliverOnMainQueue).start(next: { peer in
let isPremium = peer?.isPremium ?? false
if !isPremium {
let controller = PremiumIntroScreen(context: context, reference: reference)
let controller = PremiumIntroScreen(context: context, source: .deeplink(reference))
if let navigationController = navigationController {
navigationController.pushViewController(controller, animated: true)
}