Various improvements

This commit is contained in:
Ilya Laktyushin 2024-08-11 22:21:30 +02:00
parent 2de3528852
commit 75d884350a
5 changed files with 46 additions and 48 deletions

View File

@ -479,7 +479,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry {
} }
} }
private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, isGroup: Bool, isPublic: Bool, presentationData: PresentationData, starsState: StarsRevenueStats?, configuration: StarsSubscriptionConfiguration) -> [InviteLinksEditEntry] { private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, isGroup: Bool, isPublic: Bool, presentationData: PresentationData, configuration: StarsSubscriptionConfiguration) -> [InviteLinksEditEntry] {
var entries: [InviteLinksEditEntry] = [] var entries: [InviteLinksEditEntry] = []
entries.append(.titleHeader(presentationData.theme, presentationData.strings.InviteLink_Create_LinkNameTitle.uppercased())) entries.append(.titleHeader(presentationData.theme, presentationData.strings.InviteLink_Create_LinkNameTitle.uppercased()))
@ -492,8 +492,12 @@ private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state:
entries.append(.subscriptionFeeToggle(presentationData.theme, presentationData.strings.InviteLink_Create_Fee, state.subscriptionEnabled, isEditingEnabled)) entries.append(.subscriptionFeeToggle(presentationData.theme, presentationData.strings.InviteLink_Create_Fee, state.subscriptionEnabled, isEditingEnabled))
if state.subscriptionEnabled { if state.subscriptionEnabled {
var label: String = "" var label: String = ""
if let subscriptionFee = state.subscriptionFee, subscriptionFee > 0, let starsState { if let subscriptionFee = state.subscriptionFee, subscriptionFee > 0 {
label = presentationData.strings.InviteLink_Create_FeePerMonth("\(formatTonUsdValue(subscriptionFee, divide: false, rate: starsState.usdRate, dateTimeFormat: presentationData.dateTimeFormat))").string var usdRate = 0.012
if let usdWithdrawRate = configuration.usdWithdrawRate {
usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
}
label = presentationData.strings.InviteLink_Create_FeePerMonth("\(formatTonUsdValue(subscriptionFee, divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat))").string
} }
entries.append(.subscriptionFee(presentationData.theme, presentationData.strings.InviteLink_Create_FeePlaceholder, isEditingEnabled, state.subscriptionFee, label, configuration.maxFee)) entries.append(.subscriptionFee(presentationData.theme, presentationData.strings.InviteLink_Create_FeePlaceholder, isEditingEnabled, state.subscriptionFee, label, configuration.maxFee))
} }
@ -569,7 +573,7 @@ private struct InviteLinkEditControllerState: Equatable {
var updating = false var updating = false
} }
public func inviteLinkEditController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation?, starsState: StarsRevenueStats? = nil, completion: ((ExportedInvitation?) -> Void)? = nil) -> ViewController { public func inviteLinkEditController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation?, completion: ((ExportedInvitation?) -> Void)? = nil) -> ViewController {
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
let actionsDisposable = DisposableSet() let actionsDisposable = DisposableSet()
@ -791,7 +795,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
} }
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(invite == nil ? presentationData.strings.InviteLink_Create_Title : presentationData.strings.InviteLink_Create_EditTitle), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(invite == nil ? presentationData.strings.InviteLink_Create_Title : presentationData.strings.InviteLink_Create_EditTitle), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkEditControllerEntries(invite: invite, state: state, isGroup: isGroup, isPublic: isPublic, presentationData: presentationData, starsState: starsState, configuration: configuration), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: animateChanges) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkEditControllerEntries(invite: invite, state: state, isGroup: isGroup, isPublic: isPublic, presentationData: presentationData, configuration: configuration), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: animateChanges)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }
@ -854,22 +858,22 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio
return controller return controller
} }
private struct StarsSubscriptionConfiguration { struct StarsSubscriptionConfiguration {
static var defaultValue: StarsSubscriptionConfiguration { static var defaultValue: StarsSubscriptionConfiguration {
return StarsSubscriptionConfiguration(maxFee: 2500, usdSellRate: 2000) return StarsSubscriptionConfiguration(maxFee: 2500, usdWithdrawRate: 1200)
} }
let maxFee: Int64? let maxFee: Int64?
let usdSellRate: Int64? let usdWithdrawRate: Int64?
fileprivate init(maxFee: Int64?, usdSellRate: Int64?) { fileprivate init(maxFee: Int64?, usdWithdrawRate: Int64?) {
self.maxFee = maxFee self.maxFee = maxFee
self.usdSellRate = usdSellRate self.usdWithdrawRate = usdWithdrawRate
} }
public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration { public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration {
if let data = appConfiguration.data, let value = data["stars_subscription_amount_max"] as? Double, let usdRate = data["stars_usd_sell_rate_x1000"] as? Double { if let data = appConfiguration.data, let value = data["stars_subscription_amount_max"] as? Double, let usdRate = data["stars_usd_withdraw_rate_x1000"] as? Double {
return StarsSubscriptionConfiguration(maxFee: Int64(value), usdSellRate: Int64(usdRate)) return StarsSubscriptionConfiguration(maxFee: Int64(value), usdWithdrawRate: Int64(usdRate))
} else { } else {
return .defaultValue return .defaultValue
} }

View File

@ -268,7 +268,7 @@ private enum InviteLinksListEntry: ItemListNodeEntry {
} }
} }
private func inviteLinkListControllerEntries(presentationData: PresentationData, exportedInvitation: EngineExportedPeerInvitation?, peer: EnginePeer?, invites: [ExportedInvitation]?, revokedInvites: [ExportedInvitation]?, importers: PeerInvitationImportersState?, creators: [ExportedInvitationCreator], admin: ExportedInvitationCreator?, tick: Int32, starsState: StarsRevenueStats?) -> [InviteLinksListEntry] { private func inviteLinkListControllerEntries(presentationData: PresentationData, exportedInvitation: EngineExportedPeerInvitation?, peer: EnginePeer?, invites: [ExportedInvitation]?, revokedInvites: [ExportedInvitation]?, importers: PeerInvitationImportersState?, creators: [ExportedInvitationCreator], admin: ExportedInvitationCreator?, tick: Int32) -> [InviteLinksListEntry] {
var entries: [InviteLinksListEntry] = [] var entries: [InviteLinksListEntry] = []
if admin == nil { if admin == nil {
@ -393,7 +393,7 @@ private struct InviteLinkListControllerState: Equatable {
var revokingPrivateLink: Bool var revokingPrivateLink: Bool
} }
public func inviteLinkListController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, admin: ExportedInvitationCreator?, starsRevenueContext: StarsRevenueStatsContext? = nil) -> ViewController { public func inviteLinkListController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, admin: ExportedInvitationCreator?) -> ViewController {
var pushControllerImpl: ((ViewController) -> Void)? var pushControllerImpl: ((ViewController) -> Void)?
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)? var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
var presentInGlobalOverlayImpl: ((ViewController) -> Void)? var presentInGlobalOverlayImpl: ((ViewController) -> Void)?
@ -409,9 +409,6 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
statePromise.set(stateValue.modify { f($0) }) statePromise.set(stateValue.modify { f($0) })
} }
let starsContext: StarsRevenueStatsContext = starsRevenueContext ?? context.engine.payments.peerStarsRevenueContext(peerId: peerId)
let starsStats = Atomic<StarsRevenueStats?>(value: nil)
let revokeLinkDisposable = MetaDisposable() let revokeLinkDisposable = MetaDisposable()
actionsDisposable.add(revokeLinkDisposable) actionsDisposable.add(revokeLinkDisposable)
@ -490,7 +487,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
} }
presentControllerImpl?(shareController, nil) presentControllerImpl?(shareController, nil)
}, openMainLink: { invite in }, openMainLink: { invite in
let controller = InviteLinkViewController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, invitationsContext: nil, revokedInvitationsContext: revokedInvitesContext, importersContext: nil, starsState: starsStats.with { $0 }) let controller = InviteLinkViewController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, invitationsContext: nil, revokedInvitationsContext: revokedInvitesContext, importersContext: nil)
pushControllerImpl?(controller) pushControllerImpl?(controller)
}, copyLink: { invite in }, copyLink: { invite in
UIPasteboard.general.string = invite.link UIPasteboard.general.string = invite.link
@ -607,7 +604,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
let contextController = ContextController(presentationData: presentationData, source: .reference(InviteLinkContextReferenceContentSource(controller: controller, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) let contextController = ContextController(presentationData: presentationData, source: .reference(InviteLinkContextReferenceContentSource(controller: controller, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
presentInGlobalOverlayImpl?(contextController) presentInGlobalOverlayImpl?(contextController)
}, createLink: { }, createLink: {
let controller = inviteLinkEditController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: nil, starsState: starsStats.with( { $0 }), completion: { invite in let controller = inviteLinkEditController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: nil, completion: { invite in
if let invite = invite { if let invite = invite {
invitesContext.add(invite) invitesContext.add(invite)
} }
@ -616,7 +613,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
pushControllerImpl?(controller) pushControllerImpl?(controller)
}, openLink: { invite in }, openLink: { invite in
if let invite = invite { if let invite = invite {
let controller = InviteLinkViewController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, invitationsContext: invitesContext, revokedInvitationsContext: revokedInvitesContext, importersContext: nil, starsState: starsStats.with { $0 }) let controller = InviteLinkViewController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, invitationsContext: invitesContext, revokedInvitationsContext: revokedInvitesContext, importersContext: nil)
pushControllerImpl?(controller) pushControllerImpl?(controller)
} }
}, linkContextAction: { invite, canEdit, node, gesture in }, linkContextAction: { invite, canEdit, node, gesture in
@ -733,7 +730,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
}, action: { _, f in }, action: { _, f in
f(.default) f(.default)
let controller = inviteLinkEditController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, starsState: starsStats.with( { $0 }), completion: { invite in let controller = inviteLinkEditController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, invite: invite, completion: { invite in
if let invite = invite { if let invite = invite {
if invite.isRevoked { if invite.isRevoked {
invitesContext.remove(invite) invitesContext.remove(invite)
@ -900,14 +897,12 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
invitesContext.state, invitesContext.state,
revokedInvitesContext.state, revokedInvitesContext.state,
creators, creators,
timerPromise.get(), timerPromise.get()
starsContext.state
) )
|> map { presentationData, exportedInvitation, peer, importersContext, importers, invites, revokedInvites, creators, tick, starsState -> (ItemListControllerState, (ItemListNodeState, Any)) in |> map { presentationData, exportedInvitation, peer, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in
let previousInvites = previousInvites.swap(invites) let previousInvites = previousInvites.swap(invites)
let previousRevokedInvites = previousRevokedInvites.swap(revokedInvites) let previousRevokedInvites = previousRevokedInvites.swap(revokedInvites)
let previousCreators = previousCreators.swap(creators) let previousCreators = previousCreators.swap(creators)
let _ = starsStats.swap(starsState.stats)
var crossfade = false var crossfade = false
if (previousInvites?.hasLoadedOnce ?? false) != (invites.hasLoadedOnce) { if (previousInvites?.hasLoadedOnce ?? false) != (invites.hasLoadedOnce) {
@ -933,7 +928,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio
} }
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: title, leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: title, leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkListControllerEntries(presentationData: presentationData, exportedInvitation: exportedInvitation, peer: peer, invites: invites.hasLoadedOnce ? invites.invitations : nil, revokedInvites: revokedInvites.hasLoadedOnce ? revokedInvites.invitations : nil, importers: importers, creators: creators, admin: admin, tick: tick, starsState: starsState.stats), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: animateChanges) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkListControllerEntries(presentationData: presentationData, exportedInvitation: exportedInvitation, peer: peer, invites: invites.hasLoadedOnce ? invites.invitations : nil, revokedInvites: revokedInvites.hasLoadedOnce ? revokedInvites.invitations : nil, importers: importers, creators: creators, admin: admin, tick: tick), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: animateChanges)
return (controllerState, (listState, arguments)) return (controllerState, (listState, arguments))
} }

View File

@ -380,20 +380,18 @@ public final class InviteLinkViewController: ViewController {
private let invitationsContext: PeerExportedInvitationsContext? private let invitationsContext: PeerExportedInvitationsContext?
private let revokedInvitationsContext: PeerExportedInvitationsContext? private let revokedInvitationsContext: PeerExportedInvitationsContext?
private let importersContext: PeerInvitationImportersContext? private let importersContext: PeerInvitationImportersContext?
private let starsState: StarsRevenueStats?
private var presentationData: PresentationData private var presentationData: PresentationData
private var presentationDataDisposable: Disposable? private var presentationDataDisposable: Disposable?
fileprivate var presentationDataPromise = Promise<PresentationData>() fileprivate var presentationDataPromise = Promise<PresentationData>()
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation, invitationsContext: PeerExportedInvitationsContext?, revokedInvitationsContext: PeerExportedInvitationsContext?, importersContext: PeerInvitationImportersContext?, starsState: StarsRevenueStats? = nil) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, invite: ExportedInvitation, invitationsContext: PeerExportedInvitationsContext?, revokedInvitationsContext: PeerExportedInvitationsContext?, importersContext: PeerInvitationImportersContext?) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.invite = invite self.invite = invite
self.invitationsContext = invitationsContext self.invitationsContext = invitationsContext
self.revokedInvitationsContext = revokedInvitationsContext self.revokedInvitationsContext = revokedInvitationsContext
self.importersContext = importersContext self.importersContext = importersContext
self.starsState = starsState
self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
@ -522,6 +520,8 @@ public final class InviteLinkViewController: ViewController {
self.presentationDataPromise = Promise(self.presentationData) self.presentationDataPromise = Promise(self.presentationData)
self.controller = controller self.controller = controller
let configuration = StarsSubscriptionConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
self.importersContext = importersContext ?? context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: false)) self.importersContext = importersContext ?? context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: false))
if case let .link(_, _, _, requestApproval, _, _, _, _, _, _, _, _, _) = invite, requestApproval { if case let .link(_, _, _, requestApproval, _, _, _, _, _, _, _, _, _) = invite, requestApproval {
self.requestsContext = context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: true)) self.requestsContext = context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: true))
@ -589,15 +589,16 @@ public final class InviteLinkViewController: ViewController {
} }
}) })
}, openSubscription: { [weak self] pricing, importer in }, openSubscription: { [weak self] pricing, importer in
guard let controller = self?.controller else {
return
}
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { [weak self] peer in
guard let peer else { guard let peer else {
return return
} }
let subscriptionController = context.sharedContext.makeStarsSubscriptionScreen(context: context, peer: peer, pricing: pricing, importer: importer, usdRate: controller.starsState?.usdRate ?? 0.0) var usdRate = 0.012
if let usdWithdrawRate = configuration.usdWithdrawRate {
usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
}
let subscriptionController = context.sharedContext.makeStarsSubscriptionScreen(context: context, peer: peer, pricing: pricing, importer: importer, usdRate: usdRate)
self?.controller?.push(subscriptionController) self?.controller?.push(subscriptionController)
}) })
}, copyLink: { [weak self] invite in }, copyLink: { [weak self] invite in
@ -833,7 +834,10 @@ public final class InviteLinkViewController: ViewController {
context.account.postbox.loadedPeerWithId(adminId) context.account.postbox.loadedPeerWithId(adminId)
) |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, requestsState, creatorPeer in ) |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, requestsState, creatorPeer in
if let strongSelf = self { if let strongSelf = self {
let usdRate = strongSelf.controller?.starsState?.usdRate var usdRate = 0.012
if let usdWithdrawRate = configuration.usdWithdrawRate {
usdRate = Double(usdWithdrawRate) / 1000.0 / 100.0
}
var entries: [InviteLinkViewEntry] = [] var entries: [InviteLinkViewEntry] = []
@ -845,12 +849,8 @@ public final class InviteLinkViewController: ViewController {
var subtitle = presentationData.strings.InviteLink_SubscriptionFee_NoOneJoined var subtitle = presentationData.strings.InviteLink_SubscriptionFee_NoOneJoined
if state.count > 0 { if state.count > 0 {
title += " x \(state.count)" title += " x \(state.count)"
if let usdRate { let usdValue = formatTonUsdValue(pricing.amount * Int64(state.count), divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat)
let usdValue = formatTonUsdValue(pricing.amount * Int64(state.count), divide: false, rate: usdRate, dateTimeFormat: presentationData.dateTimeFormat) subtitle = presentationData.strings.InviteLink_SubscriptionFee_ApproximateIncome(usdValue).string
subtitle = presentationData.strings.InviteLink_SubscriptionFee_ApproximateIncome(usdValue).string
} else {
subtitle = ""
}
} }
entries.append(.subscriptionPricing(presentationData.theme, title, subtitle)) entries.append(.subscriptionPricing(presentationData.theme, title, subtitle))
} }
@ -1001,7 +1001,7 @@ public final class InviteLinkViewController: ViewController {
let revokedInvitationsContext = parentController.revokedInvitationsContext let revokedInvitationsContext = parentController.revokedInvitationsContext
if let navigationController = navigationController { if let navigationController = navigationController {
let updatedPresentationData = (self.presentationData, parentController.presentationDataPromise.get()) let updatedPresentationData = (self.presentationData, parentController.presentationDataPromise.get())
let controller = inviteLinkEditController(context: self.context, updatedPresentationData: updatedPresentationData, peerId: self.peerId, invite: self.invite, starsState: self.controller?.starsState, completion: { [weak self] invite in let controller = inviteLinkEditController(context: self.context, updatedPresentationData: updatedPresentationData, peerId: self.peerId, invite: self.invite, completion: { [weak self] invite in
if let invite = invite { if let invite = invite {
if invite.isRevoked { if invite.isRevoked {
invitationsContext?.remove(invite) invitationsContext?.remove(invite)

View File

@ -217,8 +217,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
invite: invite, invite: invite,
invitationsContext: nil, invitationsContext: nil,
revokedInvitationsContext: nil, revokedInvitationsContext: nil,
importersContext: nil, importersContext: nil
starsState: strongSelf.controller?.starsState
) )
strongSelf.pushController(controller) strongSelf.pushController(controller)
} }

View File

@ -467,7 +467,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
} }
}, },
tapAction: { attributes, _ in tapAction: { attributes, _ in
component.context.sharedContext.openExternalUrl(context: component.context, urlContext: .generic, url: strings.Stars_Purchase_Terms_URL, forceExternal: true, presentationData: presentationData, navigationController: nil, dismissInput: {}) component.context.sharedContext.openExternalUrl(context: component.context, urlContext: .generic, url: strings.Stars_Purchase_Terms_URL, forceExternal: false, presentationData: presentationData, navigationController: nil, dismissInput: {})
} }
), ),
environment: {}, environment: {},