mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
690045cf99
commit
f7ec8a0bf2
@ -27,6 +27,7 @@ public final class InAppPurchaseManager: NSObject {
|
|||||||
|
|
||||||
public enum PurchaseError {
|
public enum PurchaseError {
|
||||||
case generic
|
case generic
|
||||||
|
case cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class PaymentTransactionContext {
|
private final class PaymentTransactionContext {
|
||||||
|
@ -19,7 +19,7 @@ import ConfettiEffect
|
|||||||
import TextFormat
|
import TextFormat
|
||||||
import InstantPageCache
|
import InstantPageCache
|
||||||
|
|
||||||
public enum PremiumSource {
|
public enum PremiumSource: Equatable {
|
||||||
case settings
|
case settings
|
||||||
case stickers
|
case stickers
|
||||||
case reactions
|
case reactions
|
||||||
@ -33,6 +33,7 @@ public enum PremiumSource {
|
|||||||
case folders
|
case folders
|
||||||
case chatsPerFolder
|
case chatsPerFolder
|
||||||
case accounts
|
case accounts
|
||||||
|
case deeplink(String?)
|
||||||
|
|
||||||
var identifier: String {
|
var identifier: String {
|
||||||
switch self {
|
switch self {
|
||||||
@ -62,6 +63,12 @@ public enum PremiumSource {
|
|||||||
return "double_limits__dialog_filters_chats"
|
return "double_limits__dialog_filters_chats"
|
||||||
case .accounts:
|
case .accounts:
|
||||||
return "double_limits__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)
|
typealias EnvironmentType = (ViewControllerComponentContainer.Environment, ScrollChildEnvironment)
|
||||||
|
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
|
let source: PremiumSource
|
||||||
let isPremium: Bool?
|
let isPremium: Bool?
|
||||||
let price: String?
|
let price: String?
|
||||||
let present: (ViewController) -> Void
|
let present: (ViewController) -> Void
|
||||||
let buy: () -> Void
|
let buy: () -> Void
|
||||||
let updateIsFocused: (Bool) -> 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.context = context
|
||||||
|
self.source = source
|
||||||
self.isPremium = isPremium
|
self.isPremium = isPremium
|
||||||
self.price = price
|
self.price = price
|
||||||
self.present = present
|
self.present = present
|
||||||
@ -737,6 +746,9 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
if lhs.context !== rhs.context {
|
if lhs.context !== rhs.context {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.source != rhs.source {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.isPremium != rhs.isPremium {
|
if lhs.isPremium != rhs.isPremium {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -750,10 +762,12 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
final class State: ComponentState {
|
final class State: ComponentState {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
|
|
||||||
private var disposable: Disposable?
|
var price: String?
|
||||||
var configuration = PremiumIntroConfiguration.defaultValue
|
|
||||||
|
|
||||||
init(context: AccountContext) {
|
private var disposable: Disposable?
|
||||||
|
private(set) var configuration = PremiumIntroConfiguration.defaultValue
|
||||||
|
|
||||||
|
init(context: AccountContext, source: PremiumSource) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
@ -768,6 +782,25 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.configuration = PremiumIntroConfiguration.with(appConfiguration: appConfiguration)
|
strongSelf.configuration = PremiumIntroConfiguration.with(appConfiguration: appConfiguration)
|
||||||
strongSelf.updated(transition: .immediate)
|
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 {
|
func makeState() -> State {
|
||||||
return State(context: self.context)
|
return State(context: self.context, source: self.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var body: Body {
|
static var body: Body {
|
||||||
@ -797,6 +830,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
let scrollEnvironment = context.environment[ScrollChildEnvironment.self].value
|
let scrollEnvironment = context.environment[ScrollChildEnvironment.self].value
|
||||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||||
let state = context.state
|
let state = context.state
|
||||||
|
state.price = context.component.price
|
||||||
|
|
||||||
let theme = environment.theme
|
let theme = environment.theme
|
||||||
let strings = environment.strings
|
let strings = environment.strings
|
||||||
@ -882,7 +916,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
let present = context.component.present
|
let present = context.component.present
|
||||||
let buy = context.component.buy
|
let buy = context.component.buy
|
||||||
let updateIsFocused = context.component.updateIsFocused
|
let updateIsFocused = context.component.updateIsFocused
|
||||||
let price = context.component.price
|
|
||||||
var i = 0
|
var i = 0
|
||||||
for perk in state.configuration.perks {
|
for perk in state.configuration.perks {
|
||||||
let iconBackgroundColors = gradientColors[i]
|
let iconBackgroundColors = gradientColors[i]
|
||||||
@ -904,7 +938,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
action: {
|
action: { [weak state] in
|
||||||
var demoSubject: PremiumDemoScreen.Subject
|
var demoSubject: PremiumDemoScreen.Subject
|
||||||
switch perk {
|
switch perk {
|
||||||
case .doubleLimits:
|
case .doubleLimits:
|
||||||
@ -933,7 +967,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
let controller = PremiumDemoScreen(
|
let controller = PremiumDemoScreen(
|
||||||
context: accountContext,
|
context: accountContext,
|
||||||
subject: demoSubject,
|
subject: demoSubject,
|
||||||
source: .intro(price),
|
source: .intro(state?.price),
|
||||||
action: {
|
action: {
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
buy()
|
buy()
|
||||||
@ -947,6 +981,8 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
controller?.dismiss(animated: true, completion: nil)
|
controller?.dismiss(animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
updateIsFocused(true)
|
updateIsFocused(true)
|
||||||
|
|
||||||
|
addAppLogEvent(postbox: accountContext.account.postbox, type: "premium.promo_screen_tap", data: ["item": perk.identifier])
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
i += 1
|
i += 1
|
||||||
@ -1141,12 +1177,14 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||||
|
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
|
let source: PremiumSource
|
||||||
let updateInProgress: (Bool) -> Void
|
let updateInProgress: (Bool) -> Void
|
||||||
let present: (ViewController) -> Void
|
let present: (ViewController) -> Void
|
||||||
let completion: () -> 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.context = context
|
||||||
|
self.source = source
|
||||||
self.updateInProgress = updateInProgress
|
self.updateInProgress = updateInProgress
|
||||||
self.present = present
|
self.present = present
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
@ -1156,6 +1194,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||||||
if lhs.context !== rhs.context {
|
if lhs.context !== rhs.context {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.source != rhs.source {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1214,6 +1255,8 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept")
|
||||||
|
|
||||||
self.inProgress = true
|
self.inProgress = true
|
||||||
self.updateInProgress(true)
|
self.updateInProgress(true)
|
||||||
self.updated(transition: .immediate)
|
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 {
|
if let strongSelf = self {
|
||||||
strongSelf.inProgress = false
|
strongSelf.inProgress = false
|
||||||
strongSelf.updateInProgress(false)
|
strongSelf.updateInProgress(false)
|
||||||
strongSelf.updated(transition: .immediate)
|
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>(
|
component: ScrollComponent<EnvironmentType>(
|
||||||
content: AnyComponent(PremiumIntroScreenContentComponent(
|
content: AnyComponent(PremiumIntroScreenContentComponent(
|
||||||
context: context.component.context,
|
context: context.component.context,
|
||||||
|
source: context.component.source,
|
||||||
isPremium: state.isPremium,
|
isPremium: state.isPremium,
|
||||||
price: state.premiumProduct?.price,
|
price: state.premiumProduct?.price,
|
||||||
present: context.component.present,
|
present: context.component.present,
|
||||||
@ -1459,7 +1510,7 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer {
|
|||||||
return self._ready
|
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
|
self.context = context
|
||||||
|
|
||||||
var updateInProgressImpl: ((Bool) -> Void)?
|
var updateInProgressImpl: ((Bool) -> Void)?
|
||||||
@ -1467,6 +1518,7 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer {
|
|||||||
var completionImpl: (() -> Void)?
|
var completionImpl: (() -> Void)?
|
||||||
super.init(context: context, component: PremiumIntroScreenComponent(
|
super.init(context: context, component: PremiumIntroScreenComponent(
|
||||||
context: context,
|
context: context,
|
||||||
|
source: source,
|
||||||
updateInProgress: { inProgress in
|
updateInProgress: { inProgress in
|
||||||
updateInProgressImpl?(inProgress)
|
updateInProgressImpl?(inProgress)
|
||||||
},
|
},
|
||||||
|
@ -522,7 +522,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
|> deliverOnMainQueue).start(next: { peer in
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
let isPremium = peer?.isPremium ?? false
|
let isPremium = peer?.isPremium ?? false
|
||||||
if !isPremium {
|
if !isPremium {
|
||||||
let controller = PremiumIntroScreen(context: context, reference: reference)
|
let controller = PremiumIntroScreen(context: context, source: .deeplink(reference))
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
navigationController.pushViewController(controller, animated: true)
|
navigationController.pushViewController(controller, animated: true)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user