Various improvements

This commit is contained in:
Ilya Laktyushin 2024-08-11 14:11:09 +02:00
parent 83c7fdd228
commit fc6b6b768c
19 changed files with 136 additions and 47 deletions

View File

@ -12768,3 +12768,12 @@ Sorry for the inconvenience.";
"InviteLink.Create.RequestApprovalFeeUnavailable" = "You can't enable admin approval for links that require a monthly fee.";
"WebApp.PrivacyPolicy_URL" = "https://telegram.org/privacy-tpa";
"ChatList.SubscriptionsLowBalance.Stars_1" = "%@ Star needed";
"ChatList.SubscriptionsLowBalance.Stars_any" = "%@ Stars needed";
"ChatList.SubscriptionsLowBalance.Single.Title" = "%1$@ for %@$@";
"ChatList.SubscriptionsLowBalance.Single.Text" = "Insufficient funds to cover your subscription.";
"ChatList.SubscriptionsLowBalance.Multiple.Title" = "%@ for your subscriptions";
"ChatList.SubscriptionsLowBalance.Multiple.Text" = "Insufficient funds to cover your subscriptions.";

View File

@ -413,12 +413,28 @@ public final class ChatListContainerNode: ASDisplayNode, ASGestureRecognizerDele
var openBirthdaySetup: (() -> Void)?
var openPremiumManagement: (() -> Void)?
var openStories: ((ChatListNode.OpenStoriesSubject, ASDisplayNode?) -> Void)?
var openStarsTopup: ((Int64?) -> Void)?
var addedVisibleChatsWithPeerIds: (([EnginePeer.Id]) -> Void)?
var didBeginSelectingChats: (() -> Void)?
var canExpandHiddenItems: (() -> Bool)?
public var displayFilterLimit: (() -> Void)?
public init(context: AccountContext, controller: ChatListControllerImpl?, location: ChatListControllerLocation, chatListMode: ChatListNodeMode = .chatList(appendContacts: true), previewing: Bool, controlsHistoryPreload: Bool, isInlineMode: Bool, presentationData: PresentationData, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, filterBecameEmpty: @escaping (ChatListFilter?) -> Void, filterEmptyAction: @escaping (ChatListFilter?) -> Void, secondaryEmptyAction: @escaping () -> Void, openArchiveSettings: @escaping () -> Void) {
public init(
context: AccountContext,
controller: ChatListControllerImpl?,
location: ChatListControllerLocation,
chatListMode: ChatListNodeMode = .chatList(appendContacts: true),
previewing: Bool,
controlsHistoryPreload: Bool,
isInlineMode: Bool,
presentationData: PresentationData,
animationCache: AnimationCache,
animationRenderer: MultiAnimationRenderer,
filterBecameEmpty: @escaping (ChatListFilter?) -> Void,
filterEmptyAction: @escaping (ChatListFilter?) -> Void,
secondaryEmptyAction: @escaping () -> Void,
openArchiveSettings: @escaping () -> Void)
{
self.context = context
self.controller = controller
self.location = location

View File

@ -2825,6 +2825,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
if let sourceNode = sourceNode as? ChatListItemNode {
self.interaction.openStories?(id, sourceNode.avatarNode)
}
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})
@ -3658,19 +3659,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
} else if case .apps = key {
if let navigationController = self.navigationController {
if isRecommended {
#if DEBUG
let _ = (self.context.sharedContext.makeMiniAppListScreenInitialData(context: self.context)
|> deliverOnMainQueue).startStandalone(next: { [weak self] initialData in
guard let self, let navigationController = self.navigationController else {
return
}
navigationController.pushViewController(self.context.sharedContext.makeMiniAppListScreen(context: self.context, initialData: initialData))
})
#else
if let peerInfoScreen = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
navigationController.pushViewController(peerInfoScreen)
}
#endif
} else if case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp), let parentController = self.parentController {
self.context.sharedContext.openWebApp(
context: self.context,
@ -4659,6 +4650,7 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
}, performActiveSessionAction: { _, _ in
}, openChatFolderUpdates: {}, hideChatFolderUpdates: {
}, openStories: { _, _ in
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})

View File

@ -156,7 +156,8 @@ public final class ChatListShimmerNode: ASDisplayNode {
let interaction = ChatListNodeInteraction(context: context, animationCache: animationCache, animationRenderer: animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _, _, _ in }, togglePeerSelected: { _, _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, setPeerThreadMuted: { _, _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, setPeerThreadStopped: { _, _, _ in }, setPeerThreadPinned: { _, _, _ in }, setPeerThreadHidden: { _, _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, toggleThreadsSelection: { _, _ in }, hidePsa: { _ in }, activateChatPreview: { _, _, _, gesture, _ in
gesture?.cancel()
}, present: { _ in }, openForumThread: { _, _ in }, openStorageManagement: {}, openPasswordSetup: {}, openPremiumIntro: {}, openPremiumGift: { _ in }, openPremiumManagement: {}, openActiveSessions: {}, openBirthdaySetup: {}, performActiveSessionAction: { _, _ in }, openChatFolderUpdates: {}, hideChatFolderUpdates: {}, openStories: { _, _ in }, dismissNotice: { _ in
}, present: { _ in }, openForumThread: { _, _ in }, openStorageManagement: {}, openPasswordSetup: {}, openPremiumIntro: {}, openPremiumGift: { _ in }, openPremiumManagement: {}, openActiveSessions: {}, openBirthdaySetup: {}, performActiveSessionAction: { _, _ in }, openChatFolderUpdates: {}, hideChatFolderUpdates: {}, openStories: { _, _ in }, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})
interaction.isInlineMode = isInlineMode

View File

@ -109,6 +109,7 @@ public final class ChatListNodeInteraction {
let openChatFolderUpdates: () -> Void
let hideChatFolderUpdates: () -> Void
let openStories: (ChatListNode.OpenStoriesSubject, ASDisplayNode?) -> Void
let openStarsTopup: (Int64?) -> Void
let dismissNotice: (ChatListNotice) -> Void
let editPeer: (ChatListItem) -> Void
@ -164,6 +165,7 @@ public final class ChatListNodeInteraction {
openChatFolderUpdates: @escaping () -> Void,
hideChatFolderUpdates: @escaping () -> Void,
openStories: @escaping (ChatListNode.OpenStoriesSubject, ASDisplayNode?) -> Void,
openStarsTopup: @escaping (Int64?) -> Void,
dismissNotice: @escaping (ChatListNotice) -> Void,
editPeer: @escaping (ChatListItem) -> Void
) {
@ -206,6 +208,7 @@ public final class ChatListNodeInteraction {
self.openChatFolderUpdates = openChatFolderUpdates
self.hideChatFolderUpdates = hideChatFolderUpdates
self.openStories = openStories
self.openStarsTopup = openStarsTopup
self.dismissNotice = dismissNotice
self.editPeer = editPeer
}
@ -747,8 +750,8 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
nodeInteraction?.openPremiumGift(birthdays)
case .reviewLogin:
break
case .starsSubscriptionLowBalance:
break
case let .starsSubscriptionLowBalance(amount, _):
nodeInteraction?.openStarsTopup(amount)
}
case .hide:
nodeInteraction?.dismissNotice(notice)
@ -1087,8 +1090,8 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
nodeInteraction?.openPremiumGift(birthdays)
case .reviewLogin:
break
case .starsSubscriptionLowBalance:
break
case let .starsSubscriptionLowBalance(amount, _):
nodeInteraction?.openStarsTopup(amount)
}
case .hide:
nodeInteraction?.dismissNotice(notice)
@ -1208,6 +1211,7 @@ public final class ChatListNode: ListView {
public var openStories: ((ChatListNode.OpenStoriesSubject, ASDisplayNode?) -> Void)?
public var openBirthdaySetup: (() -> Void)?
public var openPremiumManagement: (() -> Void)?
public var openStarsTopup: ((Int64?) -> Void)?
private var theme: PresentationTheme
@ -1809,6 +1813,11 @@ public final class ChatListNode: ListView {
return
}
self.openStories?(subject, itemNode)
}, openStarsTopup: { [weak self] amount in
guard let self else {
return
}
self.openStarsTopup?(amount)
}, dismissNotice: { [weak self] notice in
guard let self else {
return
@ -1910,6 +1919,8 @@ public final class ChatListNode: ListView {
} else {
displayArchiveIntro = .single(false)
}
let starsSubscriptionsContextPromise = Promise<StarsSubscriptionsContext?>(nil)
self.updateIsMainTabDisposable = (self.isMainTab.get()
|> deliverOnMainQueue).startStrict(next: { [weak self] isMainTab in
@ -1932,9 +1943,10 @@ public final class ChatListNode: ListView {
twoStepData,
newSessionReviews(postbox: context.account.postbox),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Birthday(id: context.account.peerId)),
context.account.stateManager.contactBirthdays
context.account.stateManager.contactBirthdays,
starsSubscriptionsContextPromise.get()
)
|> mapToSignal { suggestions, dismissedSuggestions, configuration, newSessionReviews, birthday, birthdays -> Signal<ChatListNotice?, NoError> in
|> mapToSignal { suggestions, dismissedSuggestions, configuration, newSessionReviews, birthday, birthdays, starsSubscriptionsContext -> Signal<ChatListNotice?, NoError> in
if let newSessionReview = newSessionReviews.first {
return .single(.reviewLogin(newSessionReview: newSessionReview, totalCount: newSessionReviews.count))
}
@ -1968,7 +1980,24 @@ public final class ChatListNode: ListView {
todayBirthdayPeerIds = []
}
if suggestions.contains(.gracePremium) {
if suggestions.contains(.starsSubscriptionLowBalance) {
if let starsSubscriptionsContext {
return starsSubscriptionsContext.state
|> map { state in
if state.balance > 0 {
return .starsSubscriptionLowBalance(
amount: state.balance,
peers: state.subscriptions.map { $0.peer }
)
} else {
return nil
}
}
} else {
starsSubscriptionsContextPromise.set(.single(context.engine.payments.peerStarsSubscriptionsContext(starsContext: nil, missingBalance: true)))
return .single(nil)
}
} else if suggestions.contains(.gracePremium) {
return .single(.premiumGrace)
} else if suggestions.contains(.setupBirthday) && birthday == nil {
return .single(.setupBirthday)

View File

@ -90,7 +90,7 @@ public enum ChatListNotice: Equatable {
case birthdayPremiumGift(peers: [EnginePeer], birthdays: [EnginePeer.Id: TelegramBirthday])
case reviewLogin(newSessionReview: NewSessionReview, totalCount: Int)
case premiumGrace
case starsSubscriptionLowBalance(amount: Int64)
case starsSubscriptionLowBalance(amount: Int64, peers: [EnginePeer])
}
enum ChatListNodeEntry: Comparable, Identifiable {

View File

@ -11,6 +11,8 @@ import ItemListUI
import Markdown
import AccountContext
import MergedAvatarsNode
import TextNodeWithEntities
import TextFormat
class ChatListNoticeItem: ListViewItem {
enum Action {
@ -87,7 +89,7 @@ private let textFont = Font.regular(15.0)
final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
private let contentContainer: ASDisplayNode
private let titleNode: TextNode
private let textNode: TextNode
private let textNode: TextNodeWithEntities
private let arrowNode: ASImageNode
private let separatorNode: ASDisplayNode
@ -113,7 +115,7 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
self.contentContainer = ASDisplayNode()
self.titleNode = TextNode()
self.textNode = TextNode()
self.textNode = TextNodeWithEntities()
self.arrowNode = ASImageNode()
self.separatorNode = ASDisplayNode()
@ -123,7 +125,7 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
self.clipsToBounds = true
self.contentContainer.addSubnode(self.titleNode)
self.contentContainer.addSubnode(self.textNode)
self.contentContainer.addSubnode(self.textNode.textNode)
self.contentContainer.addSubnode(self.arrowNode)
self.addSubnode(self.contentContainer)
@ -153,7 +155,7 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
let previousItem = self.item
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeTextLayout = TextNode.asyncLayout(self.textNode)
let makeTextLayout = TextNodeWithEntities.asyncLayout(self.textNode)
let makeOkButtonTextLayout = TextNode.asyncLayout(self.okButtonText)
let makeCancelButtonTextLayout = TextNode.asyncLayout(self.cancelButtonText)
@ -262,10 +264,24 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
okButtonLayout = makeOkButtonTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.strings.ChatList_SessionReview_PanelConfirm, font: titleFont, textColor: item.theme.list.itemAccentColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - sideInset - rightInset, height: 100.0)))
cancelButtonLayout = makeCancelButtonTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.strings.ChatList_SessionReview_PanelReject, font: titleFont, textColor: item.theme.list.itemDestructiveColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - sideInset - rightInset, height: 100.0)))
case let .starsSubscriptionLowBalance(amount):
let titleStringValue = NSMutableAttributedString(attributedString: NSAttributedString(string: "⭐️ \(amount) Stars needed for your subscriptions", font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor))
titleString = titleStringValue
textString = NSAttributedString(string: "Insufficient funds to cover your subscriptions.", font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
case let .starsSubscriptionLowBalance(amount, peers):
let title: String
let text: String
let starsValue = item.strings.ChatList_SubscriptionsLowBalance_Stars(Int32(amount))
if let peer = peers.first, peers.count == 1 {
title = item.strings.ChatList_SubscriptionsLowBalance_Single_Title(starsValue, peer.compactDisplayTitle).string
text = item.strings.ChatList_SubscriptionsLowBalance_Single_Text
} else {
title = item.strings.ChatList_SubscriptionsLowBalance_Multiple_Title(starsValue).string
text = item.strings.ChatList_SubscriptionsLowBalance_Multiple_Text
}
let attributedTitle = NSMutableAttributedString(string: "⭐️\(title)", font: titleFont, textColor: item.theme.rootController.navigationBar.primaryTextColor)
if let range = attributedTitle.string.range(of: "⭐️") {
attributedTitle.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: attributedTitle.string))
attributedTitle.addAttribute(.baselineOffset, value: -1.0, range: NSRange(range, in: attributedTitle.string))
}
titleString = attributedTitle
textString = NSAttributedString(string: text, font: textFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
}
var leftInset: CGFloat = sideInset
@ -302,12 +318,12 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: verticalInset), size: titleLayout.0.size)
}
let _ = textLayout.1()
let _ = textLayout.1(TextNodeWithEntities.Arguments(context: item.context, cache: item.context.animationCache, renderer: item.context.animationRenderer, placeholderColor: .white, attemptSynchronous: true))
if case .center = alignment {
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: floor((params.width - textLayout.0.size.width) * 0.5), y: strongSelf.titleNode.frame.maxY + spacing), size: textLayout.0.size)
strongSelf.textNode.textNode.frame = CGRect(origin: CGPoint(x: floor((params.width - textLayout.0.size.width) * 0.5), y: strongSelf.titleNode.frame.maxY + spacing), size: textLayout.0.size)
} else {
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + spacing), size: textLayout.0.size)
strongSelf.textNode.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + spacing), size: textLayout.0.size)
}
if !avatarPeers.isEmpty {
@ -343,6 +359,8 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
hasCloseButton = true
} else if case .premiumGrace = item.notice {
hasCloseButton = true
} else if case .starsSubscriptionLowBalance = item.notice {
hasCloseButton = true
}
if let okButtonLayout, let cancelButtonLayout {
@ -387,8 +405,8 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
let buttonWidth: CGFloat = floor(buttonsWidth * 0.5)
let buttonHeight: CGFloat = 32.0
let okButtonFrame = CGRect(origin: CGPoint(x: floor((params.width - buttonsWidth) * 0.5), y: strongSelf.textNode.frame.maxY + 6.0), size: CGSize(width: buttonWidth, height: buttonHeight))
let cancelButtonFrame = CGRect(origin: CGPoint(x: okButtonFrame.maxX, y: strongSelf.textNode.frame.maxY + 6.0), size: CGSize(width: buttonWidth, height: buttonHeight))
let okButtonFrame = CGRect(origin: CGPoint(x: floor((params.width - buttonsWidth) * 0.5), y: strongSelf.textNode.textNode.frame.maxY + 6.0), size: CGSize(width: buttonWidth, height: buttonHeight))
let cancelButtonFrame = CGRect(origin: CGPoint(x: okButtonFrame.maxX, y: strongSelf.textNode.textNode.frame.maxY + 6.0), size: CGSize(width: buttonWidth, height: buttonHeight))
okButton.frame = okButtonFrame
cancelButton.frame = cancelButtonFrame

View File

@ -227,6 +227,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, ASScrollView
}, performActiveSessionAction: { _, _ in
}, openChatFolderUpdates: {}, hideChatFolderUpdates: {
}, openStories: { _, _ in
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})

View File

@ -376,6 +376,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
}, performActiveSessionAction: { _, _ in
}, openChatFolderUpdates: {}, hideChatFolderUpdates: {
}, openStories: { _, _ in
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})

View File

@ -910,7 +910,7 @@ public final class StarsTransactionsContext {
private final class StarsSubscriptionsContextImpl {
private let account: Account
private weak var starsContext: StarsContext?
private let missingBalance: Bool
private var _state: StarsSubscriptionsContext.State
private let _statePromise = Promise<StarsSubscriptionsContext.State>()
@ -923,16 +923,16 @@ private final class StarsSubscriptionsContextImpl {
private var stateDisposable: Disposable?
private let updateDisposable = MetaDisposable()
init(account: Account, starsContext: StarsContext) {
init(account: Account, starsContext: StarsContext?, missingBalance: Bool = false) {
assert(Queue.mainQueue().isCurrent())
self.account = account
self.starsContext = starsContext
self.missingBalance = missingBalance
let currentSubscriptions = starsContext.currentState?.subscriptions ?? []
let canLoadMore = starsContext.currentState?.canLoadMoreSubscriptions ?? true
let currentSubscriptions = starsContext?.currentState?.subscriptions ?? []
let canLoadMore = starsContext?.currentState?.canLoadMoreSubscriptions ?? true
self._state = StarsSubscriptionsContext.State(subscriptions: currentSubscriptions, canLoadMore: canLoadMore, isLoading: false)
self._state = StarsSubscriptionsContext.State(balance: 0, subscriptions: currentSubscriptions, canLoadMore: canLoadMore, isLoading: false)
self._statePromise.set(.single(self._state))
self.loadMore()
@ -956,7 +956,7 @@ private final class StarsSubscriptionsContextImpl {
updatedState.isLoading = true
self.updateState(updatedState)
self.disposable.set((_internal_requestStarsSubscriptions(account: self.account, peerId: self.account.peerId, offset: nextOffset, missingBalance: false)
self.disposable.set((_internal_requestStarsSubscriptions(account: self.account, peerId: self.account.peerId, offset: nextOffset, missingBalance: self.missingBalance)
|> deliverOnMainQueue).start(next: { [weak self] status in
guard let self else {
return
@ -964,6 +964,7 @@ private final class StarsSubscriptionsContextImpl {
self.nextOffset = status.nextSubscriptionsOffset
var updatedState = self._state
updatedState.balance = status.balance
updatedState.subscriptions = nextOffset.isEmpty ? status.subscriptions : updatedState.subscriptions + status.subscriptions
updatedState.isLoading = false
updatedState.canLoadMore = self.nextOffset != nil
@ -1021,11 +1022,13 @@ private final class StarsSubscriptionsContextImpl {
public final class StarsSubscriptionsContext {
public struct State: Equatable {
public var balance: Int64
public var subscriptions: [StarsContext.State.Subscription]
public var canLoadMore: Bool
public var isLoading: Bool
init(subscriptions: [StarsContext.State.Subscription], canLoadMore: Bool, isLoading: Bool) {
init(balance: Int64, subscriptions: [StarsContext.State.Subscription], canLoadMore: Bool, isLoading: Bool) {
self.balance = balance
self.subscriptions = subscriptions
self.canLoadMore = canLoadMore
self.isLoading = isLoading
@ -1052,9 +1055,9 @@ public final class StarsSubscriptionsContext {
}
}
init(account: Account, starsContext: StarsContext) {
init(account: Account, starsContext: StarsContext?, missingBalance: Bool) {
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
return StarsSubscriptionsContextImpl(account: account, starsContext: starsContext)
return StarsSubscriptionsContextImpl(account: account, starsContext: starsContext, missingBalance: missingBalance)
})
}

View File

@ -86,8 +86,8 @@ public extension TelegramEngine {
return StarsTransactionsContext(account: self.account, subject: subject, mode: mode)
}
public func peerStarsSubscriptionsContext(starsContext: StarsContext) -> StarsSubscriptionsContext {
return StarsSubscriptionsContext(account: self.account, starsContext: starsContext)
public func peerStarsSubscriptionsContext(starsContext: StarsContext?, missingBalance: Bool = false) -> StarsSubscriptionsContext {
return StarsSubscriptionsContext(account: self.account, starsContext: starsContext, missingBalance: missingBalance)
}
public func sendStarsPaymentForm(formId: Int64, source: BotPaymentInvoiceSource) -> Signal<SendBotPaymentResult, SendBotPaymentFormError> {

View File

@ -664,6 +664,8 @@ public final class ChatInlineSearchResultsListComponent: Component {
},
openStories: { _, _ in
},
openStarsTopup: { _ in
},
dismissNotice: { _ in
},
editPeer: { _ in

View File

@ -182,7 +182,8 @@ public final class LoadingOverlayNode: ASDisplayNode {
let interaction = ChatListNodeInteraction(context: context, animationCache: context.animationCache, animationRenderer: context.animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _, _, _ in }, togglePeerSelected: { _, _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, setPeerThreadMuted: { _, _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, setPeerThreadStopped: { _, _, _ in }, setPeerThreadPinned: { _, _, _ in }, setPeerThreadHidden: { _, _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, toggleThreadsSelection: { _, _ in }, hidePsa: { _ in }, activateChatPreview: { _, _, _, gesture, _ in
gesture?.cancel()
}, present: { _ in }, openForumThread: { _, _ in }, openStorageManagement: {}, openPasswordSetup: {}, openPremiumIntro: {}, openPremiumGift: { _ in }, openPremiumManagement: {}, openActiveSessions: {}, openBirthdaySetup: {}, performActiveSessionAction: { _, _ in }, openChatFolderUpdates: {}, hideChatFolderUpdates: {}, openStories: { _, _ in }, dismissNotice: { _ in
}, present: { _ in }, openForumThread: { _, _ in }, openStorageManagement: {}, openPasswordSetup: {}, openPremiumIntro: {}, openPremiumGift: { _ in }, openPremiumManagement: {}, openActiveSessions: {}, openBirthdaySetup: {}, performActiveSessionAction: { _, _ in }, openChatFolderUpdates: {}, hideChatFolderUpdates: {}, openStories: { _, _ in }, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})
@ -533,6 +534,8 @@ private final class PeerInfoScreenPersonalChannelItemNode: PeerInfoScreenItemNod
StoryContainerScreen.openPeerStories(context: item.context, peerId: item.data.peer.id, parentController: controller, avatarNode: itemNode.avatarNode)
},
openStarsTopup: { _ in
},
dismissNotice: { _ in
},
editPeer: { _ in

View File

@ -202,6 +202,8 @@ final class GreetingMessageListItemComponent: Component {
},
openStories: { _, _ in
},
openStarsTopup: { _ in
},
dismissNotice: { _ in
},
editPeer: { _ in

View File

@ -217,6 +217,8 @@ final class QuickReplySetupScreenComponent: Component {
},
openStories: { _, _ in
},
openStarsTopup: { _ in
},
dismissNotice: { _ in
},
editPeer: { [weak listNode] _ in

View File

@ -870,6 +870,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, ASScrollViewDelegate
}, performActiveSessionAction: { _, _ in
}, openChatFolderUpdates: {}, hideChatFolderUpdates: {
}, openStories: { _, _ in
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})

View File

@ -195,7 +195,13 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
return
}
var presentImpl: ((ViewController, Any?) -> Void)?
let params = WebAppParameters(source: isInline ? .inline : .simple, peerId: peer.id, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
let source: WebAppParameters.Source
if isInline {
source = .inline
} else {
source = url.isEmpty ? .generic : .simple
}
let params = WebAppParameters(source: source, peerId: peer.id, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { [weak parentController] url, concealed, commit in
ChatControllerImpl.botOpenUrl(context: context, peerId: peer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, present: { c, a in
presentImpl?(c, a)

View File

@ -290,6 +290,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, ASScrollViewDe
}, openChatFolderUpdates: {
}, hideChatFolderUpdates: {
}, openStories: { _, _ in
}, openStarsTopup: { _ in
}, dismissNotice: { _ in
}, editPeer: { _ in
})

View File

@ -172,6 +172,8 @@ private struct CommandChatInputContextPanelEntry: Comparable, Identifiable {
},
openStories: { _, _ in
},
openStarsTopup: { _ in
},
dismissNotice: { _ in
},
editPeer: { _ in