Various improvements

This commit is contained in:
Ilya Laktyushin 2024-07-24 09:25:48 +04:00
parent a7aefe85f8
commit 9ba0743553
6 changed files with 110 additions and 67 deletions

View File

@ -55,7 +55,7 @@ public final class BrowserBookmarksScreen: ViewController {
}, navigateToMessage: { _, _, _ in }, navigateToMessage: { _, _, _ in
}, navigateToMessageStandalone: { _ in }, navigateToMessageStandalone: { _ in
}, navigateToThreadMessage: { _, _, _ in }, navigateToThreadMessage: { _, _, _ in
}, tapMessage: nil, clickThroughMessage: { }, tapMessage: nil, clickThroughMessage: { _, _ in
}, toggleMessagesSelection: { _, _ in }, toggleMessagesSelection: { _, _ in
}, sendCurrentMessage: { _, _ in }, sendCurrentMessage: { _, _ in
}, sendMessage: { _ in }, sendMessage: { _ in

View File

@ -97,6 +97,7 @@ swift_library(
"//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState", "//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState",
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI", "//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
"//submodules/TelegramUI/Components/LottieComponent", "//submodules/TelegramUI/Components/LottieComponent",
"//submodules/TelegramUI/Components/LottieComponentResourceContent",
"//submodules/ImageTransparency", "//submodules/ImageTransparency",
"//submodules/GalleryUI", "//submodules/GalleryUI",
"//submodules/MediaPlayer:UniversalMediaPlayer", "//submodules/MediaPlayer:UniversalMediaPlayer",

View File

@ -1,6 +1,7 @@
import Foundation import Foundation
import UIKit import UIKit
import Display import Display
import ComponentFlow
import SwiftSignalKit import SwiftSignalKit
import AccountContext import AccountContext
import TelegramCore import TelegramCore
@ -9,6 +10,8 @@ import TelegramAnimatedStickerNode
import StickerResources import StickerResources
import MediaEditor import MediaEditor
import TelegramStringFormatting import TelegramStringFormatting
import LottieComponent
import LottieComponentResourceContent
private func generateIcon(style: DrawingWeatherEntity.Style) -> UIImage? { private func generateIcon(style: DrawingWeatherEntity.Style) -> UIImage? {
guard let image = UIImage(bundleImageName: "Chat/Attach Menu/Location") else { guard let image = UIImage(bundleImageName: "Chat/Attach Menu/Location") else {
@ -53,9 +56,8 @@ public final class DrawingWeatherEntityView: DrawingEntityView, UITextViewDelega
let backgroundView: UIView let backgroundView: UIView
let textView: DrawingTextView let textView: DrawingTextView
let iconView: UIImageView
private let imageNode: TransformImageNode private var animation = ComponentView<Empty>()
private var animationNode: AnimatedStickerNode?
private var didSetUpAnimationNode = false private var didSetUpAnimationNode = false
private let stickerFetchedDisposable = MetaDisposable() private let stickerFetchedDisposable = MetaDisposable()
@ -89,19 +91,13 @@ public final class DrawingWeatherEntityView: DrawingEntityView, UITextViewDelega
self.textView.textContainer.maximumNumberOfLines = 2 self.textView.textContainer.maximumNumberOfLines = 2
self.textView.textContainer.lineBreakMode = .byTruncatingTail self.textView.textContainer.lineBreakMode = .byTruncatingTail
self.iconView = UIImageView()
self.imageNode = TransformImageNode()
super.init(context: context, entity: entity) super.init(context: context, entity: entity)
self.textView.delegate = self self.textView.delegate = self
self.addSubview(self.backgroundView) self.addSubview(self.backgroundView)
self.addSubview(self.textView) self.addSubview(self.textView)
self.addSubview(self.iconView)
self.update(animated: false) self.update(animated: false)
self.setup()
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -134,17 +130,35 @@ public final class DrawingWeatherEntityView: DrawingEntityView, UITextViewDelega
let iconSize = min(80.0, floor(self.bounds.height * 0.7)) let iconSize = min(80.0, floor(self.bounds.height * 0.7))
let iconOffset: CGFloat = 0.3 let iconOffset: CGFloat = 0.3
self.iconView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels(iconSize * iconOffset), y: floorToScreenPixels((self.bounds.height - iconSize) / 2.0)), size: CGSize(width: iconSize, height: iconSize)) let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(iconSize * iconOffset), y: floorToScreenPixels((self.bounds.height - iconSize) / 2.0)), size: CGSize(width: iconSize, height: iconSize))
self.imageNode.frame = self.iconView.frame.offsetBy(dx: 0.0, dy: 2.0)
if let animationNode = self.animationNode { if let icon = self.weatherEntity.icon {
animationNode.frame = self.iconView.frame let _ = self.animation.update(
animationNode.updateLayout(size: self.iconView.frame.size) transition: .immediate,
component: AnyComponent(
LottieComponent(
content: LottieComponent.ResourceContent(
context: self.context,
file: icon,
attemptSynchronously: true,
providesPlaceholder: true
),
color: nil,
placeholderColor: UIColor(rgb: 0x000000, alpha: 0.1),
loop: !["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"].contains(self.weatherEntity.emoji)
)
),
environment: {},
containerSize: iconFrame.size
)
if let animationView = self.animation.view {
if animationView.superview == nil {
self.addSubview(animationView)
}
animationView.frame = iconFrame
}
} }
let imageSize = CGSize(width: iconSize, height: iconSize)
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))()
self.textView.frame = CGRect(origin: CGPoint(x: self.bounds.width - self.textSize.width - 6.0, y: floorToScreenPixels((self.bounds.height - self.textSize.height) / 2.0)), size: self.textSize) self.textView.frame = CGRect(origin: CGPoint(x: self.bounds.width - self.textSize.width - 6.0, y: floorToScreenPixels((self.bounds.height - self.textSize.height) / 2.0)), size: self.textSize)
self.backgroundView.frame = self.bounds self.backgroundView.frame = self.bounds
} }
@ -263,10 +277,8 @@ public final class DrawingWeatherEntityView: DrawingEntityView, UITextViewDelega
self.sizeToFit() self.sizeToFit()
if self.currentStyle != self.weatherEntity.style {
self.currentStyle = self.weatherEntity.style self.currentStyle = self.weatherEntity.style
self.iconView.image = generateIcon(style: self.weatherEntity.style)
}
self.backgroundView.layer.cornerRadius = self.textSize.height * 0.2 self.backgroundView.layer.cornerRadius = self.textSize.height * 0.2
if #available(iOS 13.0, *) { if #available(iOS 13.0, *) {
@ -276,42 +288,6 @@ public final class DrawingWeatherEntityView: DrawingEntityView, UITextViewDelega
super.update(animated: animated) super.update(animated: animated)
} }
private func setup() {
if let file = self.weatherEntity.icon {
self.iconView.isHidden = true
self.addSubnode(self.imageNode)
if let dimensions = file.dimensions {
if file.isAnimatedSticker || file.isVideoSticker || file.mimeType == "video/webm" {
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 256.0, height: 256.0))
if self.animationNode == nil {
let animationNode = DefaultAnimatedStickerNodeImpl()
animationNode.autoplay = true
self.animationNode = animationNode
animationNode.started = { [weak self] in
self?.imageNode.isHidden = true
}
animationNode.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: file.resource, isVideo: file.isVideoSticker), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
self.addSubnode(animationNode)
}
self.imageNode.setSignal(chatMessageAnimatedSticker(postbox: self.context.account.postbox, userLocation: .other, file: file, small: false, size: fittedDimensions))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(file), resource: file.resource).start())
} else {
if let animationNode = self.animationNode {
animationNode.visibility = false
self.animationNode = nil
animationNode.removeFromSupernode()
self.imageNode.isHidden = false
self.didSetUpAnimationNode = false
}
self.imageNode.setSignal(chatMessageSticker(account: self.context.account, userLocation: .other, file: file, small: false, synchronousLoad: false))
self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: self.context.account, userLocation: .other, fileReference: stickerPackFileReference(file), resource: chatMessageStickerResource(file: file, small: false)).start())
}
self.setNeedsLayout()
}
}
}
override func updateSelectionView() { override func updateSelectionView() {
guard let selectionView = self.selectionView as? DrawingWeatherEntitySelectionView else { guard let selectionView = self.selectionView as? DrawingWeatherEntitySelectionView else {
return return

View File

@ -86,6 +86,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
let peers: [EnginePeer.Id: EnginePeer] let peers: [EnginePeer.Id: EnginePeer]
let stateUpdated: (ComponentTransition) -> Void let stateUpdated: (ComponentTransition) -> Void
let buy: (StarsProduct) -> Void let buy: (StarsProduct) -> Void
let openAppExamples: () -> Void
init( init(
context: AccountContext, context: AccountContext,
@ -100,7 +101,8 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
expanded: Bool, expanded: Bool,
peers: [EnginePeer.Id: EnginePeer], peers: [EnginePeer.Id: EnginePeer],
stateUpdated: @escaping (ComponentTransition) -> Void, stateUpdated: @escaping (ComponentTransition) -> Void,
buy: @escaping (StarsProduct) -> Void buy: @escaping (StarsProduct) -> Void,
openAppExamples: @escaping () -> Void
) { ) {
self.context = context self.context = context
self.externalState = externalState self.externalState = externalState
@ -115,6 +117,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
self.peers = peers self.peers = peers
self.stateUpdated = stateUpdated self.stateUpdated = stateUpdated
self.buy = buy self.buy = buy
self.openAppExamples = openAppExamples
} }
static func ==(lhs: StarsPurchaseScreenContentComponent, rhs: StarsPurchaseScreenContentComponent) -> Bool { static func ==(lhs: StarsPurchaseScreenContentComponent, rhs: StarsPurchaseScreenContentComponent) -> Bool {
@ -225,15 +228,16 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: accentColor)!, theme) state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: accentColor)!, theme)
} }
let titleAttributedString = parseMarkdownIntoAttributedString(textString, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString let textAttributedString = parseMarkdownIntoAttributedString(textString, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString
if let range = titleAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 { if let range = textAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
titleAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: titleAttributedString.string)) textAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: textAttributedString.string))
} }
let openAppExamples = component.openAppExamples
let text = text.update( let text = text.update(
component: BalancedTextComponent( component: BalancedTextComponent(
text: .plain(titleAttributedString), text: .plain(textAttributedString),
horizontalAlignment: .center, horizontalAlignment: .center,
maximumNumberOfLines: 0, maximumNumberOfLines: 0,
lineSpacing: 0.2, lineSpacing: 0.2,
@ -246,6 +250,7 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
} }
}, },
tapAction: { _, _ in tapAction: { _, _ in
openAppExamples()
} }
), ),
environment: {}, environment: {},
@ -473,6 +478,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
let options: [Any] let options: [Any]
let purpose: StarsPurchasePurpose let purpose: StarsPurchasePurpose
let forceDark: Bool let forceDark: Bool
let openAppExamples: () -> Void
let updateInProgress: (Bool) -> Void let updateInProgress: (Bool) -> Void
let present: (ViewController) -> Void let present: (ViewController) -> Void
let completion: (Int64) -> Void let completion: (Int64) -> Void
@ -483,6 +489,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
options: [Any], options: [Any],
purpose: StarsPurchasePurpose, purpose: StarsPurchasePurpose,
forceDark: Bool, forceDark: Bool,
openAppExamples: @escaping () -> Void,
updateInProgress: @escaping (Bool) -> Void, updateInProgress: @escaping (Bool) -> Void,
present: @escaping (ViewController) -> Void, present: @escaping (ViewController) -> Void,
completion: @escaping (Int64) -> Void completion: @escaping (Int64) -> Void
@ -492,6 +499,7 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
self.options = options self.options = options
self.purpose = purpose self.purpose = purpose
self.forceDark = forceDark self.forceDark = forceDark
self.openAppExamples = openAppExamples
self.updateInProgress = updateInProgress self.updateInProgress = updateInProgress
self.present = present self.present = present
self.completion = completion self.completion = completion
@ -872,7 +880,8 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
}, },
buy: { [weak state] product in buy: { [weak state] product in
state?.buy(product: product) state?.buy(product: product)
} },
openAppExamples: context.component.openAppExamples
)), )),
contentInsets: UIEdgeInsets(top: environment.navigationHeight, left: 0.0, bottom: environment.safeInsets.bottom, right: 0.0), contentInsets: UIEdgeInsets(top: environment.navigationHeight, left: 0.0, bottom: environment.safeInsets.bottom, right: 0.0),
contentOffsetUpdated: { [weak state] topContentOffset, bottomContentOffset in contentOffsetUpdated: { [weak state] topContentOffset, bottomContentOffset in
@ -985,6 +994,7 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
self.context = context self.context = context
self.starsContext = starsContext self.starsContext = starsContext
var openAppExamplesImpl: (() -> Void)?
var updateInProgressImpl: ((Bool) -> Void)? var updateInProgressImpl: ((Bool) -> Void)?
var presentImpl: ((ViewController) -> Void)? var presentImpl: ((ViewController) -> Void)?
var completionImpl: ((Int64) -> Void)? var completionImpl: ((Int64) -> Void)?
@ -994,6 +1004,9 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
options: options, options: options,
purpose: purpose, purpose: purpose,
forceDark: false, forceDark: false,
openAppExamples: {
openAppExamplesImpl?()
},
updateInProgress: { inProgress in updateInProgress: { inProgress in
updateInProgressImpl?(inProgress) updateInProgressImpl?(inProgress)
}, },
@ -1011,6 +1024,19 @@ public final class StarsPurchaseScreen: ViewControllerComponentContainer {
self.navigationItem.setLeftBarButton(cancelItem, animated: false) self.navigationItem.setLeftBarButton(cancelItem, animated: false)
self.navigationPresentation = .modal self.navigationPresentation = .modal
openAppExamplesImpl = { [weak self] in
guard let self else {
return
}
let _ = (context.sharedContext.makeMiniAppListScreenInitialData(context: context)
|> deliverOnMainQueue).startStandalone(next: { [weak self] initialData in
guard let self, let navigationController = self.navigationController as? NavigationController else {
return
}
navigationController.pushViewController(context.sharedContext.makeMiniAppListScreen(context: context, initialData: initialData))
})
}
updateInProgressImpl = { [weak self] inProgress in updateInProgressImpl = { [weak self] inProgress in
if let strongSelf = self { if let strongSelf = self {
strongSelf.navigationItem.leftBarButtonItem?.isEnabled = !inProgress strongSelf.navigationItem.leftBarButtonItem?.isEnabled = !inProgress

View File

@ -34,6 +34,7 @@ swift_library(
"//submodules/TelegramUI/Components/Stars/StarsImageComponent", "//submodules/TelegramUI/Components/Stars/StarsImageComponent",
"//submodules/TelegramUI/Components/Stars/StarsAvatarComponent", "//submodules/TelegramUI/Components/Stars/StarsAvatarComponent",
"//submodules/GalleryUI", "//submodules/GalleryUI",
"//submodules/TelegramUI/Components/MiniAppListScreen",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -23,6 +23,7 @@ import UndoUI
import StarsImageComponent import StarsImageComponent
import GalleryUI import GalleryUI
import StarsAvatarComponent import StarsAvatarComponent
import MiniAppListScreen
private final class StarsTransactionSheetContent: CombinedComponent { private final class StarsTransactionSheetContent: CombinedComponent {
typealias EnvironmentType = ViewControllerComponentContainer.Environment typealias EnvironmentType = ViewControllerComponentContainer.Environment
@ -34,6 +35,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
let openPeer: (EnginePeer) -> Void let openPeer: (EnginePeer) -> Void
let openMessage: (EngineMessage.Id) -> Void let openMessage: (EngineMessage.Id) -> Void
let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void
let openAppExamples: () -> Void
let copyTransactionId: (String) -> Void let copyTransactionId: (String) -> Void
init( init(
@ -44,6 +46,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
openPeer: @escaping (EnginePeer) -> Void, openPeer: @escaping (EnginePeer) -> Void,
openMessage: @escaping (EngineMessage.Id) -> Void, openMessage: @escaping (EngineMessage.Id) -> Void,
openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void, openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void,
openAppExamples: @escaping () -> Void,
copyTransactionId: @escaping (String) -> Void copyTransactionId: @escaping (String) -> Void
) { ) {
self.context = context self.context = context
@ -53,6 +56,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
self.openPeer = openPeer self.openPeer = openPeer
self.openMessage = openMessage self.openMessage = openMessage
self.openMedia = openMedia self.openMedia = openMedia
self.openAppExamples = openAppExamples
self.copyTransactionId = copyTransactionId self.copyTransactionId = copyTransactionId
} }
@ -345,6 +349,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
photo = nil photo = nil
isRefund = false isRefund = false
isGift = true isGift = true
delayedCloseOnOpenPeer = false
} }
if let spaceRegex { if let spaceRegex {
let nsRange = NSRange(descriptionText.startIndex..., in: descriptionText) let nsRange = NSRange(descriptionText.startIndex..., in: descriptionText)
@ -647,6 +652,8 @@ private final class StarsTransactionSheetContent: CombinedComponent {
var descriptionSize: CGSize = .zero var descriptionSize: CGSize = .zero
if !descriptionText.isEmpty { if !descriptionText.isEmpty {
let openAppExamples = component.openAppExamples
if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== environment.theme { if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== environment.theme {
state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: linkColor)!, theme) state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: linkColor)!, theme)
} }
@ -665,7 +672,18 @@ private final class StarsTransactionSheetContent: CombinedComponent {
text: .plain(attributedString), text: .plain(attributedString),
horizontalAlignment: .center, horizontalAlignment: .center,
maximumNumberOfLines: 5, maximumNumberOfLines: 5,
lineSpacing: 0.2 lineSpacing: 0.2,
highlightColor: linkColor.withAlphaComponent(0.2),
highlightAction: { attributes in
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)
} else {
return nil
}
},
tapAction: { _, _ in
openAppExamples()
}
), ),
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude),
transition: .immediate transition: .immediate
@ -765,6 +783,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
let openPeer: (EnginePeer) -> Void let openPeer: (EnginePeer) -> Void
let openMessage: (EngineMessage.Id) -> Void let openMessage: (EngineMessage.Id) -> Void
let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void
let openAppExamples: () -> Void
let copyTransactionId: (String) -> Void let copyTransactionId: (String) -> Void
init( init(
@ -774,6 +793,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
openPeer: @escaping (EnginePeer) -> Void, openPeer: @escaping (EnginePeer) -> Void,
openMessage: @escaping (EngineMessage.Id) -> Void, openMessage: @escaping (EngineMessage.Id) -> Void,
openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void, openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void,
openAppExamples: @escaping () -> Void,
copyTransactionId: @escaping (String) -> Void copyTransactionId: @escaping (String) -> Void
) { ) {
self.context = context self.context = context
@ -782,6 +802,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
self.openPeer = openPeer self.openPeer = openPeer
self.openMessage = openMessage self.openMessage = openMessage
self.openMedia = openMedia self.openMedia = openMedia
self.openAppExamples = openAppExamples
self.copyTransactionId = copyTransactionId self.copyTransactionId = copyTransactionId
} }
@ -826,6 +847,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
openPeer: context.component.openPeer, openPeer: context.component.openPeer,
openMessage: context.component.openMessage, openMessage: context.component.openMessage,
openMedia: context.component.openMedia, openMedia: context.component.openMedia,
openAppExamples: context.component.openAppExamples,
copyTransactionId: context.component.copyTransactionId copyTransactionId: context.component.copyTransactionId
)), )),
backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor), backgroundColor: .color(environment.theme.actionSheet.opaqueItemBackgroundColor),
@ -915,6 +937,7 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
var openPeerImpl: ((EnginePeer) -> Void)? var openPeerImpl: ((EnginePeer) -> Void)?
var openMessageImpl: ((EngineMessage.Id) -> Void)? var openMessageImpl: ((EngineMessage.Id) -> Void)?
var openMediaImpl: (([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void)? var openMediaImpl: (([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void)?
var openAppExamplesImpl: (() -> Void)?
var copyTransactionIdImpl: ((String) -> Void)? var copyTransactionIdImpl: ((String) -> Void)?
super.init( super.init(
context: context, context: context,
@ -931,6 +954,9 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
openMedia: { media, transitionNode, addToTransitionSurface in openMedia: { media, transitionNode, addToTransitionSurface in
openMediaImpl?(media, transitionNode, addToTransitionSurface) openMediaImpl?(media, transitionNode, addToTransitionSurface)
}, },
openAppExamples: {
openAppExamplesImpl?()
},
copyTransactionId: { transactionId in copyTransactionId: { transactionId in
copyTransactionIdImpl?(transactionId) copyTransactionIdImpl?(transactionId)
} }
@ -1018,6 +1044,19 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
})) }))
} }
openAppExamplesImpl = { [weak self] in
guard let self else {
return
}
let _ = (context.sharedContext.makeMiniAppListScreenInitialData(context: context)
|> deliverOnMainQueue).startStandalone(next: { [weak self] initialData in
guard let self, let navigationController = self.navigationController as? NavigationController else {
return
}
navigationController.pushViewController(context.sharedContext.makeMiniAppListScreen(context: context, initialData: initialData))
})
}
copyTransactionIdImpl = { [weak self] transactionId in copyTransactionIdImpl = { [weak self] transactionId in
guard let self else { guard let self else {
return return