diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 65019d171b..65d1e9bb7a 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -12247,6 +12247,11 @@ Sorry for the inconvenience."; "Stars.Intro.Transaction.FragmentTopUp.Subtitle" = "via Fragment"; "Stars.Intro.Transaction.Unsupported.Title" = "Unsupported"; +"Stars.Intro.PurchasedTitle" = "Stars Acquired"; +"Stars.Intro.PurchasedText" = "**%@** added to your balance."; +"Stars.Intro.PurchasedText.Stars_1" = "%@ Star"; +"Stars.Intro.PurchasedText.Stars_any" = "%@ Stars"; + "Stars.Purchase.GetStars" = "Get Stars"; "Stars.Purchase.GetStarsInfo" = "Choose how many Stars you would like to buy."; diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 4396a1bf18..b318177283 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1127,6 +1127,7 @@ public protocol AccountContext: AnyObject { var wallpaperUploadManager: WallpaperUploadManager? { get } var watchManager: WatchManager? { get } var inAppPurchaseManager: InAppPurchaseManager? { get } + var starsContext: StarsContext? { get } var currentLimitsConfiguration: Atomic { get } var currentContentSettings: Atomic { get } diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index d0db28a125..0893dbe865 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -299,9 +299,11 @@ public struct ChatControllerInitialBotAppStart { public enum ChatControllerInteractionNavigateToPeer { public struct InfoParams { public let switchToRecommendedChannels: Bool + public let ignoreInSavedMessages: Bool - public init(switchToRecommendedChannels: Bool) { + public init(switchToRecommendedChannels: Bool = false, ignoreInSavedMessages: Bool = false) { self.switchToRecommendedChannels = switchToRecommendedChannels + self.ignoreInSavedMessages = ignoreInSavedMessages } } diff --git a/submodules/PhoneNumberFormat/Sources/PhoneNumbers.swift b/submodules/PhoneNumberFormat/Sources/PhoneNumbers.swift index 55189173f0..468652c8a6 100644 --- a/submodules/PhoneNumberFormat/Sources/PhoneNumbers.swift +++ b/submodules/PhoneNumberFormat/Sources/PhoneNumbers.swift @@ -5,17 +5,6 @@ import TelegramCore private let phoneNumberUtil = NBPhoneNumberUtil() -public func enhancePhoneNumberWithCodeFromNumber(_ phoneNumber: String, otherPhoneNumber: String, configuration: CountriesConfiguration) -> String { - guard let (_, code) = lookupCountryIdByNumber(otherPhoneNumber, configuration: configuration) else { - return phoneNumber - } - var cleanNumber = cleanPhoneNumber(phoneNumber) - while cleanNumber.hasPrefix("0") { - cleanNumber.removeFirst() - } - return "+\(code)\(cleanNumber)" -} - public func cleanPhoneNumber(_ text: String, removePlus: Bool = false) -> String { var result = "" for c in text { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift index be0a5d2c0f..38efb68fd6 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift @@ -113,13 +113,7 @@ private final class StarsContextImpl { private let account: Account private let peerId: EnginePeer.Id - private var _state: StarsContext.State? { - didSet { - if self._state != oldValue { - self._statePromise.set(.single(self._state)) - } - } - } + private var _state: StarsContext.State? private let _statePromise = Promise() var state: Signal { return self._statePromise.get() @@ -145,7 +139,7 @@ private final class StarsContextImpl { guard let self, let state = self._state, let balance = balances[peerId] else { return } - self._state = StarsContext.State(balance: balance, transactions: state.transactions, canLoadMore: nextOffset != nil, isLoading: false) + self.updateState(StarsContext.State(flags: [], balance: balance, transactions: state.transactions, canLoadMore: nextOffset != nil, isLoading: false)) self.load() }) } @@ -162,22 +156,20 @@ private final class StarsContextImpl { self.disposable.set((_internal_requestStarsState(account: self.account, peerId: self.peerId, offset: nil) |> deliverOnMainQueue).start(next: { [weak self] status in if let self { - self._state = StarsContext.State(balance: status.balance, transactions: status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false) + self.updateState(StarsContext.State(flags: [], balance: status.balance, transactions: status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false)) self.nextOffset = status.nextOffset - - self.loadMore() } })) } func add(balance: Int64) { - if var state = self._state { - var transactions = state.transactions - transactions.insert(.init(id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil), at: 0) - - state.balance = state.balance + balance - self._state = state + guard let state = self._state else { + return } + var transactions = state.transactions + transactions.insert(.init(id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil), at: 0) + + self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: state.balance + balance, transactions: transactions, canLoadMore: state.canLoadMore, isLoading: state.isLoading)) } func loadMore() { @@ -192,11 +184,16 @@ private final class StarsContextImpl { self.disposable.set((_internal_requestStarsState(account: self.account, peerId: self.peerId, offset: nextOffset) |> deliverOnMainQueue).start(next: { [weak self] status in if let self { - self._state = StarsContext.State(balance: status.balance, transactions: currentState.transactions + status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false) + self.updateState(StarsContext.State(flags: [], balance: status.balance, transactions: currentState.transactions + status.transactions, canLoadMore: status.nextOffset != nil, isLoading: false)) self.nextOffset = status.nextOffset } })) } + + private func updateState(_ state: StarsContext.State) { + self._state = state + self._statePromise.set(.single(state)) + } } private extension StarsContext.State.Transaction { @@ -265,11 +262,24 @@ public final class StarsContext { } } + public struct Flags: OptionSet { + public var rawValue: Int32 + + public init(rawValue: Int32) { + self.rawValue = rawValue + } + + public static let isPendingBalance = Flags(rawValue: 1 << 0) + } + + public var flags: Flags public var balance: Int64 public var transactions: [Transaction] public var canLoadMore: Bool public var isLoading: Bool - init(balance: Int64, transactions: [Transaction], canLoadMore: Bool, isLoading: Bool) { + + init(flags: Flags, balance: Int64, transactions: [Transaction], canLoadMore: Bool, isLoading: Bool) { + self.flags = flags self.balance = balance self.transactions = transactions self.canLoadMore = canLoadMore @@ -277,6 +287,9 @@ public final class StarsContext { } public static func == (lhs: State, rhs: State) -> Bool { + if lhs.flags != rhs.flags { + return true + } if lhs.balance != rhs.balance { return false } @@ -313,6 +326,12 @@ public final class StarsContext { } } + public func load() { + self.impl.with { + $0.load() + } + } + public func loadMore() { self.impl.with { $0.loadMore() diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index cd33ef2627..2bf7e916c0 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -11931,7 +11931,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc } if isSettings { - self.starsContext = context.engine.payments.peerStarsContext(peerId: context.account.peerId) + self.starsContext = context.starsContext } else { self.starsContext = nil } diff --git a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift index 1e0e552a7f..48b2be4a04 100644 --- a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift +++ b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift @@ -305,7 +305,7 @@ public final class PremiumStarComponent: Component { ] for name in names { - if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first { + if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first, color.rgb != 0x6a94ff { particleSystem.particleColor = color particleSystem.particleColorVariation = SCNVector4Make(0, 0, 0, 0) } diff --git a/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift b/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift index bcc1890cbd..b1613b5e1f 100644 --- a/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift @@ -53,6 +53,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent { let context: AccountContext let externalState: ExternalState let containerSize: CGSize + let balance: Int64? let options: [StarsTopUpOption] let peerId: EnginePeer.Id? let requiredStars: Int64? @@ -67,6 +68,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent { context: AccountContext, externalState: ExternalState, containerSize: CGSize, + balance: Int64?, options: [StarsTopUpOption], peerId: EnginePeer.Id?, requiredStars: Int64?, @@ -80,6 +82,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent { self.context = context self.externalState = externalState self.containerSize = containerSize + self.balance = balance self.options = options self.peerId = peerId self.requiredStars = requiredStars @@ -300,14 +303,20 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent { var i = 0 var items: [AnyComponentWithIdentity] = [] - - if let products = state.products { + + if let products = state.products, let balance = context.component.balance { + var minimumCount: Int64? + if let requiredStars = context.component.requiredStars { + minimumCount = requiredStars - balance + } for product in products { - if let requiredStars = context.component.requiredStars, requiredStars > product.option.count { + if let minimumCount, minimumCount > product.option.count { continue } - if !context.component.expanded && !initialValues.contains(product.option.count) { + if let _ = minimumCount, items.isEmpty { + + } else if !context.component.expanded && !initialValues.contains(product.option.count) { continue } @@ -799,6 +808,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent { context: context.component.context, externalState: contentExternalState, containerSize: context.availableSize, + balance: state.starsState?.balance, options: context.component.options, peerId: context.component.peerId, requiredStars: context.component.requiredStars, diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift index a8ea6c7deb..100c8fcb75 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift @@ -17,6 +17,7 @@ import PremiumStarComponent import ListSectionComponent import BundleIconComponent import TextFormat +import UndoUI final class StarsTransactionsScreenComponent: Component { typealias EnvironmentType = ViewControllerComponentContainer.Environment @@ -719,10 +720,26 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer { return } self.starsContext.add(balance: stars) + + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let resultController = UndoOverlayController( + presentationData: presentationData, + content: .image( + image: UIImage(bundleImageName: "Premium/Stars/StarMedium")!, + title: presentationData.strings.Stars_Intro_PurchasedTitle, + text: presentationData.strings.Stars_Intro_PurchasedText(presentationData.strings.Stars_Intro_PurchasedText_Stars(Int32(stars))).string, + round: false, + undoText: nil + ), + elevatedLayout: false, + action: { _ in return true}) + self.present(resultController, in: .window(.root)) }) self.push(controller) }) } + + self.starsContext.load() } required public init(coder aDecoder: NSCoder) { diff --git a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift index 80b86126df..bb7982eae8 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift @@ -59,6 +59,7 @@ private final class SheetContent: CombinedComponent { var cachedStarImage: (UIImage, PresentationTheme)? private let context: AccountContext + private let starsContext: StarsContext private let source: BotPaymentInvoiceSource private let invoice: TelegramMediaInvoice @@ -67,6 +68,8 @@ private final class SheetContent: CombinedComponent { private(set) var balance: Int64? private(set) var form: BotPaymentForm? + private var stateDisposable: Disposable? + private var optionsDisposable: Disposable? private(set) var options: [StarsTopUpOption] = [] { didSet { @@ -79,11 +82,13 @@ private final class SheetContent: CombinedComponent { init( context: AccountContext, + starsContext: StarsContext, source: BotPaymentInvoiceSource, invoice: TelegramMediaInvoice, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError> ) { self.context = context + self.starsContext = starsContext self.source = source self.invoice = invoice @@ -109,10 +114,20 @@ private final class SheetContent: CombinedComponent { }) } }) + + self.stateDisposable = (starsContext.state + |> deliverOnMainQueue).start(next: { [weak self] state in + guard let self else { + return + } + self.balance = state?.balance + self.updated(transition: .immediate) + }) } deinit { self.peerDisposable?.dispose() + self.stateDisposable?.dispose() self.optionsDisposable?.dispose() } @@ -140,16 +155,33 @@ private final class SheetContent: CombinedComponent { self.updated() } let _ = (self.optionsPromise.get() - |> filter { $0 != nil} + |> filter { $0 != nil } |> take(1) |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in if let self { self.inProgress = false self.updated() + + requestTopUp({ [weak self] in + guard let self else { + return + } + self.inProgress = true + self.updated() + + let _ = (self.starsContext.state + |> filter { state in + if let state { + return !state.flags.contains(.isPendingBalance) + } + return false + } + |> take(1) + |> deliverOnMainQueue).start(next: { _ in + action() + }) + }) } - requestTopUp({ - action() - }) }) } else { action() @@ -158,7 +190,7 @@ private final class SheetContent: CombinedComponent { } func makeState() -> State { - return State(context: self.context, source: self.source, invoice: self.invoice, inputData: self.inputData) + return State(context: self.context, starsContext: self.starsContext, source: self.source, invoice: self.invoice, inputData: self.inputData) } static var body: Body { @@ -366,7 +398,9 @@ private final class SheetContent: CombinedComponent { requiredStars: invoice.totalAmount, completion: { [weak starsContext] stars in starsContext?.add(balance: stars) - completion() + Queue.mainQueue().after(0.1) { + completion() + } } ) controller?.push(purchaseController) @@ -375,7 +409,7 @@ private final class SheetContent: CombinedComponent { let resultController = UndoOverlayController( presentationData: presentationData, content: .image( - image: UIImage(bundleImageName: "Premium/Stars/StarLarge")!, + image: UIImage(bundleImageName: "Premium/Stars/StarMedium")!, title: presentationData.strings.Stars_Transfer_PurchasedTitle, text: presentationData.strings.Stars_Transfer_PurchasedText(invoice.title, botTitle, presentationData.strings.Stars_Transfer_Purchased_Stars(Int32(invoice.totalAmount))).string, round: false, @@ -386,6 +420,8 @@ private final class SheetContent: CombinedComponent { controller?.present(resultController, in: .window(.root)) controller?.dismissAnimated() + + starsContext.load() }) } ), @@ -530,6 +566,8 @@ public final class StarsTransferScreen: ViewControllerComponentContainer { ) self.navigationPresentation = .flatModal + + starsContext.load() } required public init(coder aDecoder: NSCoder) { diff --git a/submodules/TelegramUI/Sources/AccountContext.swift b/submodules/TelegramUI/Sources/AccountContext.swift index 4677d5071c..a96aa6768b 100644 --- a/submodules/TelegramUI/Sources/AccountContext.swift +++ b/submodules/TelegramUI/Sources/AccountContext.swift @@ -127,6 +127,7 @@ public final class AccountContextImpl: AccountContext { public let wallpaperUploadManager: WallpaperUploadManager? private let themeUpdateManager: ThemeUpdateManager? public let inAppPurchaseManager: InAppPurchaseManager? + public let starsContext: StarsContext? public let peerChannelMemberCategoriesContextsManager = PeerChannelMemberCategoriesContextsManager() @@ -294,11 +295,13 @@ public final class AccountContextImpl: AccountContext { self.themeUpdateManager = ThemeUpdateManagerImpl(sharedContext: sharedContext, account: account) self.inAppPurchaseManager = InAppPurchaseManager(engine: self.engine) + self.starsContext = self.engine.payments.peerStarsContext(peerId: account.peerId) } else { self.prefetchManager = nil self.wallpaperUploadManager = nil self.themeUpdateManager = nil self.inAppPurchaseManager = nil + self.starsContext = nil } if let locationManager = self.sharedContextImpl.locationManager, sharedContext.applicationBindings.isMainApp && !temp { diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift index 51c60e5da6..2c4108565f 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift @@ -131,8 +131,14 @@ extension ChatControllerImpl { switch navigation { case let .info(params): var recommendedChannels = false - if let params, params.switchToRecommendedChannels { - recommendedChannels = true + if let params { + if params.switchToRecommendedChannels { + recommendedChannels = true + } + if params.ignoreInSavedMessages && currentPeerId == self.context.account.peerId { + self.playShakeAnimation() + return + } } self.navigationButtonAction(.openChatInfo(expandAvatar: expandAvatar, recommendedChannels: recommendedChannels)) case let .chat(textInputState, _, _): diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPhoneContextMenu.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPhoneContextMenu.swift index 6bc840ce03..b332e0a4d0 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPhoneContextMenu.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenPhoneContextMenu.swift @@ -45,7 +45,13 @@ extension ChatControllerImpl: MFMessageComposeViewControllerDelegate { source = .location(ChatMessageContextLocationContentSource(controller: self, location: messageNode.view.convert(messageNode.bounds, to: nil).origin.offsetBy(dx: location.x, dy: location.y))) } else { source = .extracted(ChatMessagePhoneContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode)) -// source = .extracted(ChatMessageContextExtractedContentSource(chatController: self, chatNode: self.chatDisplayNode, engine: self.context.engine, message: message, selectAll: false)) + } + + let phoneNumber: String + if let peer, case let .user(user) = peer, let phone = user.phone { + phoneNumber = "+\(phone)" + } else { + phoneNumber = number } var items: [ContextMenuItem] = [] @@ -55,7 +61,7 @@ extension ChatControllerImpl: MFMessageComposeViewControllerDelegate { return } let basicData = DeviceContactBasicData(firstName: "", lastName: "", phoneNumbers: [ - DeviceContactPhoneNumberData(label: "", value: number) + DeviceContactPhoneNumberData(label: "", value: phoneNumber) ]) let contactData = DeviceContactExtendedData(basicData: basicData, middleName: "", prefix: "", suffix: "", organization: "", jobTitle: "", department: "", emailAddresses: [], urls: [], addresses: [], birthdayDate: nil, socialProfiles: [], instantMessagingProfiles: [], note: "") @@ -121,7 +127,7 @@ extension ChatControllerImpl: MFMessageComposeViewControllerDelegate { guard let self else { return } - self.openUrl("tel:\(number)", concealed: false) + self.openUrl("tel:\(phoneNumber)", concealed: false) })) ) } @@ -158,7 +164,7 @@ extension ChatControllerImpl: MFMessageComposeViewControllerDelegate { guard let self else { return } - self.openPeer(peer: peer, navigation: .info(nil), fromMessage: nil) + self.openPeer(peer: peer, navigation: .info(ChatControllerInteractionNavigateToPeer.InfoParams(ignoreInSavedMessages: true)), fromMessage: nil) })) ) } else { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 7ca41224b4..8e37ddc588 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -2941,8 +2941,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G |> `catch` { _ -> Signal in return .single(nil) }) - if invoice.currency == "XTR" { - let starsContext = strongSelf.context.engine.payments.peerStarsContext(peerId: strongSelf.context.account.peerId) + if invoice.currency == "XTR", let starsContext = strongSelf.context.starsContext { let starsInputData = combineLatest( inputData.get(), starsContext.state diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index c117929b1c..4116410c7b 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -824,8 +824,7 @@ func openResolvedUrlImpl( |> `catch` { _ -> Signal in return .single(nil) }) - if invoice.currency == "XTR" { - let starsContext = context.engine.payments.peerStarsContext(peerId: context.account.peerId) + if invoice.currency == "XTR", let starsContext = context.starsContext { let starsInputData = combineLatest( inputData.get(), starsContext.state diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index 49c4d92664..fae7d484b7 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -864,8 +864,7 @@ public final class WebAppController: ViewController, AttachmentContainable { |> `catch` { _ -> Signal in return .single(nil) }) - if invoice.currency == "XTR" { - let starsContext = strongSelf.context.engine.payments.peerStarsContext(peerId: strongSelf.context.account.peerId) + if invoice.currency == "XTR", let starsContext = strongSelf.context.starsContext { let starsInputData = combineLatest( inputData.get(), starsContext.state