mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Various improvements
This commit is contained in:
parent
a7aefe85f8
commit
9ba0743553
@ -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
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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,16 +130,34 @@ 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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user