diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 8293c75c9f..2f4efe6f2f 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1005,6 +1005,7 @@ public protocol SharedAccountContext: AnyObject { func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController + func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction, peer: EnginePeer) -> ViewController func makeStarsReceiptScreen(context: AccountContext, receipt: BotPaymentReceipt) -> ViewController func makeStarsSubscriptionScreen(context: AccountContext, subscription: StarsContext.State.Subscription, update: @escaping (Bool) -> Void) -> ViewController diff --git a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift index 4cec283b1b..f1b96e8970 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift @@ -22,13 +22,25 @@ import TextFormat private final class InviteLinkEditControllerArguments { let context: AccountContext let updateState: ((InviteLinkEditControllerState) -> InviteLinkEditControllerState) -> Void + let focusOnItem: (InviteLinksEditEntryTag) -> Void + let errorWithItem: (InviteLinksEditEntryTag) -> Void let scrollToUsage: () -> Void let dismissInput: () -> Void let revoke: () -> Void - init(context: AccountContext, updateState: @escaping ((InviteLinkEditControllerState) -> InviteLinkEditControllerState) -> Void, scrollToUsage: @escaping () -> Void, dismissInput: @escaping () -> Void, revoke: @escaping () -> Void) { + init( + context: AccountContext, + updateState: @escaping ((InviteLinkEditControllerState) -> InviteLinkEditControllerState) -> Void, + focusOnItem: @escaping (InviteLinksEditEntryTag) -> Void, + errorWithItem: @escaping (InviteLinksEditEntryTag) -> Void, + scrollToUsage: @escaping () -> Void, + dismissInput: @escaping () -> Void, + revoke: @escaping () -> Void) + { self.context = context self.updateState = updateState + self.focusOnItem = focusOnItem + self.errorWithItem = errorWithItem self.scrollToUsage = scrollToUsage self.dismissInput = dismissInput self.revoke = revoke @@ -45,6 +57,7 @@ private enum InviteLinksEditSection: Int32 { } private enum InviteLinksEditEntryTag: ItemListItemTag { + case subscriptionFee case usage func isEqual(to other: ItemListItemTag) -> Bool { @@ -79,7 +92,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry { case subscriptionFeeToggle(PresentationTheme, String, Bool, Bool) - case subscriptionFee(PresentationTheme, String, Bool, Int64?, String) + case subscriptionFee(PresentationTheme, String, Bool, Int64?, String, Int64?) case subscriptionFeeInfo(PresentationTheme, String) case requestApproval(PresentationTheme, String, Bool, Bool) @@ -182,8 +195,8 @@ private enum InviteLinksEditEntry: ItemListNodeEntry { } else { return false } - case let .subscriptionFee(lhsTheme, lhsText, lhsValue, lhsEnabled, lhsLabel): - if case let .subscriptionFee(rhsTheme, rhsText, rhsValue, rhsEnabled, rhsLabel) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsEnabled == rhsEnabled, lhsLabel == rhsLabel { + case let .subscriptionFee(lhsTheme, lhsText, lhsValue, lhsEnabled, lhsLabel, lhsMaxValue): + if case let .subscriptionFee(rhsTheme, rhsText, rhsValue, rhsEnabled, rhsLabel, rhsMaxValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsEnabled == rhsEnabled, lhsLabel == rhsLabel, lhsMaxValue == rhsMaxValue { return true } else { return false @@ -300,17 +313,26 @@ private enum InviteLinksEditEntry: ItemListNodeEntry { } return updatedState } + if value { + Queue.mainQueue().after(0.1) { + arguments.focusOnItem(.subscriptionFee) + } + } }) - case let .subscriptionFee(_, placeholder, enabled, value, label): + case let .subscriptionFee(_, placeholder, enabled, value, label, maxValue): let title = NSMutableAttributedString(string: "⭐️", font: Font.semibold(18.0), textColor: .white) if let range = title.string.range(of: "⭐️") { title.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: title.string)) title.addAttribute(.baselineOffset, value: -1.0, range: NSRange(range, in: title.string)) } - return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, title: title, text: value.flatMap { "\($0)" } ?? "", placeholder: placeholder, label: label, type: .number, spacing: 3.0, enabled: enabled, sectionId: self.section, textUpdated: { text in + return ItemListSingleLineInputItem(context: arguments.context, presentationData: presentationData, title: title, text: value.flatMap { "\($0)" } ?? "", placeholder: placeholder, label: label, type: .number, spacing: 3.0, enabled: enabled, tag: InviteLinksEditEntryTag.subscriptionFee, sectionId: self.section, textUpdated: { text in arguments.updateState { state in var updatedState = state - if let value = Int64(text) { + if var value = Int64(text) { + if let maxValue, value > maxValue { + value = maxValue + arguments.errorWithItem(.subscriptionFee) + } updatedState.subscriptionFee = value } else { updatedState.subscriptionFee = nil @@ -457,7 +479,7 @@ private enum InviteLinksEditEntry: ItemListNodeEntry { } } -private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, isGroup: Bool, isPublic: Bool, presentationData: PresentationData, starsState: StarsRevenueStats?) -> [InviteLinksEditEntry] { +private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: InviteLinkEditControllerState, isGroup: Bool, isPublic: Bool, presentationData: PresentationData, starsState: StarsRevenueStats?, configuration: StarsSubscriptionConfiguration) -> [InviteLinksEditEntry] { var entries: [InviteLinksEditEntry] = [] entries.append(.titleHeader(presentationData.theme, presentationData.strings.InviteLink_Create_LinkNameTitle.uppercased())) @@ -472,9 +494,9 @@ private func inviteLinkEditControllerEntries(invite: ExportedInvitation?, state: if state.subscriptionEnabled { var label: String = "" if let subscriptionFee = state.subscriptionFee, subscriptionFee > 0, let starsState { - label = formatTonUsdValue(subscriptionFee, divide: false, rate: starsState.usdRate, dateTimeFormat: presentationData.dateTimeFormat) + label = "≈\(formatTonUsdValue(subscriptionFee, divide: false, rate: starsState.usdRate, dateTimeFormat: presentationData.dateTimeFormat)) / month" } - entries.append(.subscriptionFee(presentationData.theme, "Stars amount per month", isEditingEnabled, state.subscriptionFee, label)) + entries.append(.subscriptionFee(presentationData.theme, "Stars amount per month", isEditingEnabled, state.subscriptionFee, label, configuration.maxFee)) } let infoText: String if let _ = invite, state.subscriptionEnabled { @@ -585,9 +607,15 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio var dismissImpl: (() -> Void)? var dismissInputImpl: (() -> Void)? var scrollToUsageImpl: (() -> Void)? + var focusImpl: ((InviteLinksEditEntryTag) -> Void)? + var errorImpl: ((InviteLinksEditEntryTag) -> Void)? let arguments = InviteLinkEditControllerArguments(context: context, updateState: { f in updateState(f) + }, focusOnItem: { tag in + focusImpl?(tag) + }, errorWithItem: { tag in + errorImpl?(tag) }, scrollToUsage: { scrollToUsageImpl?() }, dismissInput: { @@ -648,6 +676,8 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData + let configuration = StarsSubscriptionConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + let previousState = Atomic(value: nil) let signal = combineLatest( presentationData, @@ -762,7 +792,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 listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: inviteLinkEditControllerEntries(invite: invite, state: state, isGroup: isGroup, isPublic: isPublic, presentationData: presentationData, starsState: starsState), 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, starsState: starsState, configuration: configuration), style: .blocks, emptyStateItem: nil, crossfadeState: false, animateChanges: animateChanges) return (controllerState, (listState, arguments)) } @@ -806,5 +836,41 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio dismissImpl = { [weak controller] in controller?.dismiss() } + focusImpl = { [weak controller] targetTag in + controller?.forEachItemNode { itemNode in + if let itemNode = itemNode as? ItemListSingleLineInputItemNode, let tag = itemNode.tag, tag.isEqual(to: targetTag) { + itemNode.focus() + } + } + } + let hapticFeedback = HapticFeedback() + errorImpl = { [weak controller] targetTag in + hapticFeedback.error() + controller?.forEachItemNode { itemNode in + if let itemNode = itemNode as? ItemListSingleLineInputItemNode, let tag = itemNode.tag, tag.isEqual(to: targetTag) { + itemNode.animateError() + } + } + } return controller } + +private struct StarsSubscriptionConfiguration { + static var defaultValue: StarsSubscriptionConfiguration { + return StarsSubscriptionConfiguration(maxFee: 2500) + } + + let maxFee: Int64? + + fileprivate init(maxFee: Int64?) { + self.maxFee = maxFee + } + + public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration { + if let data = appConfiguration.data, let value = data["stars_subscription_amount_max"] as? Double { + return StarsSubscriptionConfiguration(maxFee: Int64(value)) + } else { + return .defaultValue + } + } +} diff --git a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift index 4aaaf7df8d..81dc1224b2 100644 --- a/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift +++ b/submodules/ItemListUI/Sources/Items/ItemListSingleLineInputItem.swift @@ -141,6 +141,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg private let textNode: TextFieldNode private let clearIconNode: ASImageNode private let clearButtonNode: HighlightableButtonNode + private let labelNode: TextNode private var item: ItemListSingleLineInputItem? @@ -171,12 +172,17 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg self.clearButtonNode = HighlightableButtonNode() + self.labelNode = TextNode() + self.labelNode.isUserInteractionEnabled = false + super.init(layerBacked: false, dynamicBounce: false) self.addSubnode(self.titleNode.textNode) self.addSubnode(self.textNode) self.addSubnode(self.clearIconNode) self.addSubnode(self.clearButtonNode) + self.addSubnode(self.textNode) + self.addSubnode(self.labelNode) self.clearButtonNode.addTarget(self, action: #selector(self.clearButtonPressed), forControlEvents: .touchUpInside) self.clearButtonNode.highligthedChanged = { [weak self] highlighted in @@ -218,6 +224,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg let makeTitleLayout = TextNode.asyncLayout(self.titleNode.textNode) let makeTitleWithEntitiesLayout = TextNodeWithEntities.asyncLayout(self.titleNode) let makeMeasureTitleSizeLayout = TextNode.asyncLayout(self.measureTitleSizeNode) + let makeLabelLayout = TextNode.asyncLayout(self.labelNode) let currentItem = self.item @@ -262,6 +269,8 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg let (measureTitleLayout, measureTitleSizeApply) = makeMeasureTitleSizeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "A", font: Font.regular(item.presentationData.fontSize.itemListBaseFontSize)), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - 32.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.label ?? "", font: Font.regular(item.presentationData.fontSize.itemListBaseFontSize), textColor: item.presentationData.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - 32.0 - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let separatorHeight = UIScreenPixel let contentSize = CGSize(width: params.width, height: max(titleLayout.size.height, measureTitleLayout.size.height) + 22.0) @@ -310,6 +319,7 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg strongSelf.titleNode.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floor((layout.contentSize.height - titleLayout.size.height) / 2.0)), size: titleLayout.size) let _ = measureTitleSizeApply() + let _ = labelApply() let secureEntry: Bool let capitalizationType: UITextAutocapitalizationType @@ -379,6 +389,8 @@ public class ItemListSingleLineInputItemNode: ListViewItemNode, UITextFieldDeleg strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset + titleLayout.size.width + item.spacing, y: 0.0), size: CGSize(width: max(1.0, params.width - (leftInset + rightInset + titleLayout.size.width + item.spacing)), height: layout.contentSize.height - 2.0)) + strongSelf.labelNode.frame = CGRect(origin: CGPoint(x: layoutSize.width - rightInset - labelLayout.size.width, y: floorToScreenPixels((layout.contentSize.height - labelLayout.size.height) / 2.0)), size: labelLayout.size) + switch item.alignment { case .default: strongSelf.textNode.textField.textAlignment = .natural diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift index c92d845045..72c24c4b94 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift @@ -911,6 +911,7 @@ private final class StarsSubscriptionsContextImpl { private let disposable = MetaDisposable() private var stateDisposable: Disposable? + private let updateDisposable = MetaDisposable() init(account: Account, starsContext: StarsContext) { assert(Queue.mainQueue().isCurrent()) @@ -931,6 +932,7 @@ private final class StarsSubscriptionsContextImpl { assert(Queue.mainQueue().isCurrent()) self.disposable.dispose() self.stateDisposable?.dispose() + self.updateDisposable.dispose() } func loadMore() { @@ -978,6 +980,7 @@ private final class StarsSubscriptionsContextImpl { updatedState.subscriptions[index] = updatedSubscription } self.updateState(updatedState) + self.updateDisposable.set(_internal_updateStarsSubscription(account: self.account, peerId: self.account.peerId, subscriptionId: id, cancel: cancel).startStrict()) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift index 022720b8ef..14fc327d3f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift @@ -93,9 +93,5 @@ public extension TelegramEngine { public func sendStarsPaymentForm(formId: Int64, source: BotPaymentInvoiceSource) -> Signal { return _internal_sendStarsPaymentForm(account: self.account, formId: formId, source: source) } - - public func updateStarsSubscription(peerId: EnginePeer.Id, subscriptionId: String, cancel: Bool) -> Signal { - return _internal_updateStarsSubscription(account: self.account, peerId: peerId, subscriptionId: subscriptionId, cancel: cancel) - } } } diff --git a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift index 4824033937..b0dc0a709e 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift @@ -29,6 +29,7 @@ private final class SheetContent: CombinedComponent { let source: BotPaymentInvoiceSource let extendedMedia: [TelegramExtendedMedia] let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + let navigateToPeer: (EnginePeer) -> Void let dismiss: () -> Void init( @@ -38,6 +39,7 @@ private final class SheetContent: CombinedComponent { source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + navigateToPeer: @escaping (EnginePeer) -> Void, dismiss: @escaping () -> Void ) { self.context = context @@ -46,6 +48,7 @@ private final class SheetContent: CombinedComponent { self.source = source self.extendedMedia = extendedMedia self.inputData = inputData + self.navigateToPeer = navigateToPeer self.dismiss = dismiss } @@ -77,6 +80,7 @@ private final class SheetContent: CombinedComponent { private var peerDisposable: Disposable? private(set) var balance: Int64? private(set) var form: BotPaymentForm? + private(set) var navigateToPeer: (EnginePeer) -> Void private var stateDisposable: Disposable? @@ -96,13 +100,15 @@ private final class SheetContent: CombinedComponent { source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], invoice: TelegramMediaInvoice, - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + navigateToPeer: @escaping (EnginePeer) -> Void ) { self.context = context self.starsContext = starsContext self.source = source self.extendedMedia = extendedMedia self.invoice = invoice + self.navigateToPeer = navigateToPeer super.init() @@ -159,6 +165,7 @@ private final class SheetContent: CombinedComponent { return } + let navigateToPeer = self.navigateToPeer let action = { [weak self] in guard let self else { return @@ -167,8 +174,19 @@ private final class SheetContent: CombinedComponent { self.updated() let _ = (self.context.engine.payments.sendStarsPaymentForm(formId: form.id, source: self.source) - |> deliverOnMainQueue).start(next: { _ in + |> deliverOnMainQueue).start(next: { [weak self] _ in + guard let self else { + return + } completion(true) + if case let .starsChatSubscription(link) = self.source { + let _ = (self.context.engine.peers.joinLinkInformation(link) + |> deliverOnMainQueue).startStandalone(next: { result in + if case let .alreadyJoined(peer) = result { + navigateToPeer(peer) + } + }) + } }, error: { [weak self] error in guard let self else { return @@ -235,7 +253,7 @@ private final class SheetContent: CombinedComponent { } func makeState() -> State { - return State(context: self.context, starsContext: self.starsContext, source: self.source, extendedMedia: self.extendedMedia, invoice: self.invoice, inputData: self.inputData) + return State(context: self.context, starsContext: self.starsContext, source: self.source, extendedMedia: self.extendedMedia, invoice: self.invoice, inputData: self.inputData, navigateToPeer: self.navigateToPeer) } static var body: Body { @@ -639,6 +657,7 @@ private final class StarsTransferSheetComponent: CombinedComponent { private let source: BotPaymentInvoiceSource private let extendedMedia: [TelegramExtendedMedia] private let inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + private let navigateToPeer: (EnginePeer) -> Void init( context: AccountContext, @@ -646,7 +665,8 @@ private final class StarsTransferSheetComponent: CombinedComponent { invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], - inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> + inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + navigateToPeer: @escaping (EnginePeer) -> Void ) { self.context = context self.starsContext = starsContext @@ -654,6 +674,7 @@ private final class StarsTransferSheetComponent: CombinedComponent { self.source = source self.extendedMedia = extendedMedia self.inputData = inputData + self.navigateToPeer = navigateToPeer } static func ==(lhs: StarsTransferSheetComponent, rhs: StarsTransferSheetComponent) -> Bool { @@ -687,6 +708,7 @@ private final class StarsTransferSheetComponent: CombinedComponent { source: context.component.source, extendedMedia: context.component.extendedMedia, inputData: context.component.inputData, + navigateToPeer: context.component.navigateToPeer, dismiss: { animateOut.invoke(Action { _ in if let controller = controller() { @@ -747,6 +769,7 @@ public final class StarsTransferScreen: ViewControllerComponentContainer { source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia] = [], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, + navigateToPeer: @escaping (EnginePeer) -> Void = { _ in }, completion: @escaping (Bool) -> Void ) { self.context = context @@ -761,7 +784,8 @@ public final class StarsTransferScreen: ViewControllerComponentContainer { invoice: invoice, source: source, extendedMedia: extendedMedia, - inputData: inputData + inputData: inputData, + navigateToPeer: navigateToPeer ), navigationBarAppearance: .none, statusBarStyle: .ignore, diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index ca19a40983..7cd2153142 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -323,7 +323,8 @@ func openResolvedUrlImpl( } } let _ = (starsInputData |> filter { $0 != nil } |> take(1) |> deliverOnMainQueue).start(next: { _ in - let controller = context.sharedContext.makeStarsTransferScreen(context: context, starsContext: starsContext, invoice: invoice, source: .starsChatSubscription(hash: link), extendedMedia: [], inputData: starsInputData, completion: { _ in + let controller = context.sharedContext.makeStarsSubscriptionTransferScreen(context: context, starsContext: starsContext, invoice: invoice, link: link, inputData: starsInputData, navigateToPeer: { peer in + openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil)) }) navigationController?.pushViewController(controller) }) diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index f6df7e2a9f..5ce56c2bc8 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -2743,6 +2743,10 @@ public final class SharedAccountContextImpl: SharedAccountContext { return StarsTransferScreen(context: context, starsContext: starsContext, invoice: invoice, source: source, extendedMedia: extendedMedia, inputData: inputData, completion: completion) } + public func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController { + return StarsTransferScreen(context: context, starsContext: starsContext, invoice: invoice, source: .starsChatSubscription(hash: link), extendedMedia: [], inputData: inputData, navigateToPeer: navigateToPeer, completion: { _ in }) + } + public func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction, peer: EnginePeer) -> ViewController { return StarsTransactionScreen(context: context, subject: .transaction(transaction, peer)) }