Merge commit '43931c9157e2615e4aac57ee34dc9fc2929096cf' into beta

This commit is contained in:
Ali 2023-11-02 21:20:50 +04:00
commit 74a73fb41c
47 changed files with 284 additions and 128 deletions

View File

@ -893,7 +893,7 @@ public protocol SharedAccountContext: AnyObject {
func chatAvailableMessageActions(engine: TelegramEngine, accountPeerId: EnginePeer.Id, messageIds: Set<EngineMessage.Id>, messages: [EngineMessage.Id: EngineMessage], peers: [EnginePeer.Id: EnginePeer]) -> Signal<ChatAvailableMessageActions, NoError>
func resolveUrl(context: AccountContext, peerId: PeerId?, url: String, skipUrlAuth: Bool) -> Signal<ResolvedUrl, NoError>
func resolveUrlWithProgress(context: AccountContext, peerId: PeerId?, url: String, skipUrlAuth: Bool) -> Signal<ResolveUrlResult, NoError>
func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)?, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?)
func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)?, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?, progress: Promise<Bool>?)
func openAddContact(context: AccountContext, firstName: String, lastName: String, phoneNumber: String, label: String, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, completed: @escaping () -> Void)
func openAddPersonContact(context: AccountContext, peerId: PeerId, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void)
func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void)

View File

@ -208,7 +208,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
present(c, a)
}, dismissInput: {
self?.dismissInput()
}, contentContext: nil)
}, contentContext: nil, progress: nil)
})
}, clearRecentSearch: { [weak self] in
guard let strongSelf = self else {

View File

@ -264,7 +264,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
} else {
UIPasteboard.general.setData(data, forPasteboardType: dataType)
}
context.sharedContext.openResolvedUrl(.importStickers, context: context, urlContext: .generic, navigationController: arguments.getNavigationController(), forceExternal: false, openPeer: { _, _ in }, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { c, a in arguments.presentController(c, a as? ViewControllerPresentationArguments) }, dismissInput: {}, contentContext: nil)
context.sharedContext.openResolvedUrl(.importStickers, context: context, urlContext: .generic, navigationController: arguments.getNavigationController(), forceExternal: false, openPeer: { _, _ in }, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { c, a in arguments.presentController(c, a as? ViewControllerPresentationArguments) }, dismissInput: {}, contentContext: nil, progress: nil)
}
})
case .sendLogs:

View File

@ -1369,7 +1369,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
self?.present(c, a)
}, dismissInput: {
self?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}
}
}))

View File

@ -370,13 +370,13 @@ private final class PremiumGiftCodeSheetContent: CombinedComponent {
component: AnyComponent(
Button(
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: giftReason, font: tableFont, textColor: giftCode.messageId != nil ? tableLinkColor : tableTextColor)))),
isEnabled: true,
automaticHighlight: giftCode.messageId != nil,
action: {
if let messageId = giftCode.messageId {
component.openMessage(messageId)
}
Queue.mainQueue().after(1.0) {
component.cancel(false)
Queue.mainQueue().after(1.0) {
component.cancel(false)
}
}
}
)
@ -391,13 +391,13 @@ private final class PremiumGiftCodeSheetContent: CombinedComponent {
component: AnyComponent(
Button(
content: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: giftReason, font: tableFont, textColor: boost.giveawayMessageId != nil ? tableLinkColor : tableTextColor)))),
isEnabled: true,
automaticHighlight: boost.giveawayMessageId != nil,
action: {
if let messageId = boost.giveawayMessageId {
component.openMessage(messageId)
}
Queue.mainQueue().after(1.0) {
component.cancel(false)
Queue.mainQueue().after(1.0) {
component.cancel(false)
}
}
}
)

View File

@ -2043,7 +2043,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { [weak controller] c, arguments in
controller?.push(c)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
})
}
}

View File

@ -916,7 +916,7 @@ private final class QrCodeScanScreenNode: ViewControllerTracingNode, UIScrollVie
self?.controller?.present(c, in: .window(.root), with: a)
}, dismissInput: { [weak self] in
self?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
return true
}

View File

@ -318,7 +318,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { controller, arguments in
pushControllerImpl?(controller)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
})
}
@ -359,7 +359,7 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { controller, arguments in
pushControllerImpl?(controller)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
})
}

View File

@ -225,7 +225,7 @@ public func logoutOptionsController(context: AccountContext, navigationControlle
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { controller, arguments in
pushControllerImpl?(controller)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
})
}

View File

@ -1068,7 +1068,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { controller, arguments in
present(.push, controller)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
})
})
allItems.append(faq)

View File

@ -2217,7 +2217,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
}
}
} else if let emojiString = self.emojiString, emojiString.count == 1 {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
if shouldPlay {
@ -2298,7 +2298,7 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
})
} else {
return .optionalAction({
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
})
}
} else if let dice = self.telegramDice {

View File

@ -12,7 +12,7 @@ private let sharedBackgroundImage = generateStretchableFilledCircleImage(radius:
public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButtonNode {
private let textNode: TextNode
private var iconView: UIImageView?
private let shimmerEffectNode: ShimmerEffectForegroundNode
private var shimmerEffectNode: ShimmerEffectForegroundNode?
private var backgroundView: UIImageView?
@ -26,12 +26,8 @@ public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButton
self.textNode = TextNode()
self.textNode.isUserInteractionEnabled = false
self.shimmerEffectNode = ShimmerEffectForegroundNode()
self.shimmerEffectNode.cornerRadius = 5.0
super.init()
self.addSubnode(self.shimmerEffectNode)
self.addSubnode(self.textNode)
self.highligthedChanged = { [weak self] highlighted in
@ -58,18 +54,32 @@ public final class ChatMessageAttachedContentButtonNode: HighlightTrackingButton
guard let titleColor = self.titleColor else {
return
}
self.shimmerEffectNode.isHidden = false
self.shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let shimmerEffectNode: ShimmerEffectForegroundNode
if let current = self.shimmerEffectNode {
shimmerEffectNode = current
} else {
shimmerEffectNode = ShimmerEffectForegroundNode()
shimmerEffectNode.cornerRadius = 5.0
self.insertSubnode(shimmerEffectNode, at: 0)
self.shimmerEffectNode = shimmerEffectNode
}
shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let backgroundFrame = self.bounds
self.shimmerEffectNode.frame = backgroundFrame
self.shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: titleColor.withAlphaComponent(0.3), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
shimmerEffectNode.frame = backgroundFrame
shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: titleColor.withAlphaComponent(0.3), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
}
public func stopShimmering() {
self.shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
self?.shimmerEffectNode.isHidden = true
guard let shimmerEffectNode = self.shimmerEffectNode else {
return
}
self.shimmerEffectNode = nil
shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak shimmerEffectNode] _ in
shimmerEffectNode?.removeFromSupernode()
})
}

View File

@ -4221,11 +4221,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let item = self.item {
if let type = self.backgroundNode.type, case .none = type {
return .optionalAction({
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
})
} else {
return .action(InternalBubbleTapAction.Action {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
})
}
}

View File

@ -23,6 +23,7 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentButtonNode",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -13,6 +13,7 @@ import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageAttachedContentButtonNode
import ChatControllerInteraction
private let avatarFont = avatarPlaceholderFont(size: 16.0)
@ -390,14 +391,14 @@ public class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
@objc private func contactTap(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
}
@objc private func buttonPressed() {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}

View File

@ -22,6 +22,7 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -12,6 +12,7 @@ import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageInteractiveFileNode
import ChatControllerInteraction
public class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
public let interactiveFileNode: ChatMessageInteractiveFileNode
@ -47,7 +48,7 @@ public class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
self.interactiveFileNode.activateLocalContent = { [weak self] in
if let strongSelf = self, let item = strongSelf.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
@ -86,7 +87,7 @@ public class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
override public func accessibilityActivate() -> Bool {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
return true
}

View File

@ -39,7 +39,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
private let placeholderNode: StickerShimmerEffectNode
private let animationNode: AnimatedStickerNode
private let shimmerEffectNode: ShimmerEffectForegroundNode
private var shimmerEffectNode: ShimmerEffectForegroundNode?
private let buttonNode: HighlightTrackingButtonNode
private let buttonStarsNode: PremiumStarsNode
private let buttonTitleNode: TextNode
@ -49,6 +49,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
private var isPlaying: Bool = false
private var currentProgressDisposable: Disposable?
override public var visibility: ListViewItemNodeVisibility {
didSet {
let wasVisible = oldValue != .none
@ -94,10 +96,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.clipsToBounds = true
self.buttonNode.cornerRadius = 17.0
self.shimmerEffectNode = ShimmerEffectForegroundNode()
self.shimmerEffectNode.cornerRadius = 17.0
self.placeholderNode = StickerShimmerEffectNode()
self.placeholderNode.isUserInteractionEnabled = false
self.placeholderNode.alpha = 0.75
@ -120,7 +119,6 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
self.addSubnode(self.animationNode)
self.addSubnode(self.buttonNode)
self.buttonNode.addSubnode(self.shimmerEffectNode)
self.buttonNode.addSubnode(self.buttonStarsNode)
self.addSubnode(self.buttonTitleNode)
@ -149,32 +147,68 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
deinit {
self.animationDisposable?.dispose()
self.currentProgressDisposable?.dispose()
}
@objc private func buttonPressed() {
guard let item = self.item else {
return
}
let _ = item.controllerInteraction.openMessage(item.message, .default)
self.startShimmering()
Queue.mainQueue().after(0.75) {
self.stopShimmering()
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default, progress: self.makeProgress()))
}
private func makeProgress() -> Promise<Bool> {
let progress = Promise<Bool>()
self.currentProgressDisposable?.dispose()
self.currentProgressDisposable = (progress.get()
|> distinctUntilChanged
|> deliverOnMainQueue).start(next: { [weak self] hasProgress in
guard let self else {
return
}
self.displayProgress = hasProgress
})
return progress
}
private var displayProgress = false {
didSet {
if self.displayProgress != oldValue {
if self.displayProgress {
self.startShimmering()
} else {
self.stopShimmering()
}
}
}
}
func startShimmering() {
self.shimmerEffectNode.isHidden = false
self.shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
private func startShimmering() {
let shimmerEffectNode: ShimmerEffectForegroundNode
if let current = self.shimmerEffectNode {
shimmerEffectNode = current
} else {
shimmerEffectNode = ShimmerEffectForegroundNode()
shimmerEffectNode.cornerRadius = 17.0
self.buttonNode.insertSubnode(shimmerEffectNode, at: 0)
self.shimmerEffectNode = shimmerEffectNode
}
shimmerEffectNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
let backgroundFrame = self.buttonNode.frame
self.shimmerEffectNode.frame = CGRect(origin: .zero, size: backgroundFrame.size)
self.shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: UIColor.white.withAlphaComponent(0.2), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
shimmerEffectNode.frame = CGRect(origin: .zero, size: backgroundFrame.size)
shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: backgroundFrame.size), within: backgroundFrame.size)
shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: UIColor.white.withAlphaComponent(0.15), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
}
func stopShimmering() {
self.shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
self?.shimmerEffectNode.isHidden = true
private func stopShimmering() {
guard let shimmerEffectNode = self.shimmerEffectNode else {
return
}
self.shimmerEffectNode = nil
shimmerEffectNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak shimmerEffectNode] _ in
shimmerEffectNode?.removeFromSupernode()
})
}

View File

@ -28,6 +28,7 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentButtonNode",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -18,7 +18,7 @@ import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageAttachedContentButtonNode
import UndoUI
import ChatControllerInteraction
private let titleFont = Font.medium(15.0)
private let textFont = Font.regular(13.0)
@ -68,7 +68,7 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode
}
}
private var setupTimestamp: Double?
private var currentProgressDisposable: Disposable?
required public init() {
self.placeholderNode = StickerShimmerEffectNode()
@ -137,22 +137,26 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode
item.controllerInteraction.openPeer(peer, .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
}
}
override public func accessibilityActivate() -> Bool {
self.buttonPressed()
return true
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.currentProgressDisposable?.dispose()
}
override public func didLoad() {
super.didLoad()
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.bubbleTap(_:)))
self.view.addGestureRecognizer(tapRecognizer)
}
override public func accessibilityActivate() -> Bool {
self.buttonPressed()
return true
}
@objc private func bubbleTap(_ gestureRecognizer: UITapGestureRecognizer) {
guard let item = self.item else {
@ -592,7 +596,33 @@ public class ChatMessageGiveawayBubbleContentNode: ChatMessageBubbleContentNode
@objc private func buttonPressed() {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default, progress: self.makeProgress()))
}
}
private func makeProgress() -> Promise<Bool> {
let progress = Promise<Bool>()
self.currentProgressDisposable?.dispose()
self.currentProgressDisposable = (progress.get()
|> distinctUntilChanged
|> deliverOnMainQueue).start(next: { [weak self] hasProgress in
guard let self else {
return
}
self.displayProgress = hasProgress
})
return progress
}
private var displayProgress = false {
didSet {
if self.displayProgress != oldValue {
if self.displayProgress {
self.buttonNode.startShimmering()
} else {
self.buttonNode.stopShimmering()
}
}
}
}

View File

@ -23,6 +23,7 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveInstantVideoNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -13,6 +13,7 @@ import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageInteractiveInstantVideoNode
import ChatMessageInteractiveFileNode
import ChatControllerInteraction
extension ChatMessageInteractiveInstantVideoNode.AnimateFileNodeDescription {
convenience init(_ node: ChatMessageInteractiveFileNode) {
@ -127,7 +128,7 @@ public class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentN
self.interactiveFileNode.activateLocalContent = { [weak self] in
if let strongSelf = self, let item = strongSelf.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
@ -166,7 +167,7 @@ public class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentN
override public func accessibilityActivate() -> Bool {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
return true
}

View File

@ -1419,7 +1419,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
item.context.sharedContext.mediaManager.playlistControl(.playback(.togglePlayPause), type: .voice)
}
} else {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
@ -1573,7 +1573,7 @@ public class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
}
}
if canPlay {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
})
}

View File

@ -23,6 +23,7 @@ swift_library(
"//submodules/TelegramPresentationData",
"//submodules/TelegramUIPreferences",
"//submodules/TelegramStringFormatting",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
"//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",

View File

@ -13,6 +13,7 @@ import LiveLocationPositionNode
import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatControllerInteraction
private let titleFont = Font.medium(14.0)
private let liveTitleFont = Font.medium(16.0)
@ -47,7 +48,7 @@ public class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
override public func accessibilityActivate() -> Bool {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
return true
}
@ -511,7 +512,7 @@ public class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
@objc private func imageTap(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
if let item = self.item {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
}

View File

@ -14,6 +14,7 @@ import ChatMessageDateAndStatusNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatMessageInteractiveMediaNode
import ChatControllerInteraction
public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
override public var supportsMosaic: Bool {
@ -52,7 +53,7 @@ public class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
case .automaticPlayback:
openChatMessageMode = .automaticPlayback
}
let _ = item.controllerInteraction.openMessage(item.message, openChatMessageMode)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: openChatMessageMode))
}
}
}

View File

@ -30,6 +30,7 @@ swift_library(
"//submodules/Markdown",
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -20,6 +20,7 @@ import GalleryUI
import Markdown
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatControllerInteraction
public class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleContentNode {
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
@ -142,7 +143,7 @@ public class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleCont
guard let item = self.item else {
return
}
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {

View File

@ -1416,7 +1416,7 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
if let item = self.item, self.imageNode.frame.contains(location) {
return .optionalAction({
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
})
}

View File

@ -33,6 +33,7 @@ swift_library(
"//submodules/AvatarNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -23,6 +23,7 @@ import AvatarStoryIndicatorComponent
import AvatarNode
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import ChatControllerInteraction
public class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode {
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
@ -136,7 +137,7 @@ public class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode {
guard let item = self.item else {
return
}
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, unboundSize: CGSize?, maxWidth: CGFloat, layout: (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {

View File

@ -31,6 +31,7 @@ swift_library(
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
"//submodules/TelegramUI/Components/WallpaperPreviewMedia",
"//submodules/TelegramUI/Components/ChatControllerInteraction",
],
visibility = [
"//visibility:public",

View File

@ -21,6 +21,7 @@ import AudioTranscriptionPendingIndicatorComponent
import ChatMessageBubbleContentNode
import ChatMessageItemCommon
import WallpaperPreviewMedia
import ChatControllerInteraction
public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
@ -181,7 +182,7 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode
guard let item = self.item else {
return
}
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
private func updateProgress(_ progress: Float?) {

View File

@ -91,7 +91,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
case .automaticPlayback:
openChatMessageMode = .automaticPlayback
}
if !item.controllerInteraction.openMessage(item.message, openChatMessageMode) {
if !item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: openChatMessageMode)) {
if let webPage = strongSelf.webPage, case let .Loaded(content) = webPage.content {
var isConcealed = true
if item.message.text.contains(content.url) {
@ -123,7 +123,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
}
if let webpage = webPageContent {
if webpage.story != nil {
let _ = item.controllerInteraction.openMessage(item.message, .default)
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
} else if webpage.instantPage != nil {
strongSelf.contentNode.openMedia?(.default)
} else {

View File

@ -1068,7 +1068,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self?.presentController(c, .window(.root), a)
}, dismissInput: {
self?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
case .wallpaper:
break
case .theme:

View File

@ -85,6 +85,16 @@ public struct NavigateToMessageParams {
}
}
public struct OpenMessageParams {
public var mode: ChatControllerInteractionOpenMessageMode
public var progress: Promise<Bool>?
public init(mode: ChatControllerInteractionOpenMessageMode, progress: Promise<Bool>? = nil) {
self.mode = mode
self.progress = progress
}
}
public final class ChatControllerInteraction {
public enum OpenPeerSource {
case `default`
@ -110,7 +120,7 @@ public final class ChatControllerInteraction {
}
}
public let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool
public let openMessage: (Message, OpenMessageParams) -> Bool
public let openPeer: (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void
public let openPeerMention: (String, Promise<Bool>?) -> Void
public let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void
@ -228,7 +238,7 @@ public final class ChatControllerInteraction {
public var enableFullTranslucency: Bool = true
public init(
openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool,
openMessage: @escaping (Message, OpenMessageParams) -> Bool,
openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer, MessageReference?, OpenPeerSource) -> Void,
openPeerMention: @escaping (String, Promise<Bool>?) -> Void,
openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void,

View File

@ -26,6 +26,7 @@ import AppBundle
import ChatControllerInteraction
import InvisibleInkDustNode
import MediaPickerUI
import ChatControllerInteraction
public enum PeerInfoPaneKey: Int32 {
case members
@ -1384,7 +1385,7 @@ public final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode,
let listItemInteraction = ListMessageItemInteraction(
openMessage: { message, mode in
return chatControllerInteraction.openMessage(message, mode)
return chatControllerInteraction.openMessage(message, OpenMessageParams(mode: mode))
},
openMessageContextMenu: { message, bool, node, rect, gesture in
chatControllerInteraction.openMessageContextMenu(message, bool, node, rect, gesture, nil)
@ -1469,7 +1470,7 @@ public final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode,
}
strongSelf.chatControllerInteraction.toggleMessagesSelection([item.message.id], toggledValue)
} else {
let _ = strongSelf.chatControllerInteraction.openMessage(item.message, .default)
let _ = strongSelf.chatControllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default))
}
}
@ -1561,7 +1562,7 @@ public final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode,
self._itemInteraction = VisualMediaItemInteraction(
openMessage: { [weak self] message in
let _ = self?.chatControllerInteraction.openMessage(message, .default)
let _ = self?.chatControllerInteraction.openMessage(message, OpenMessageParams(mode: .default))
},
openMessageContextActions: { [weak self] message, sourceNode, sourceRect, gesture in
self?.chatControllerInteraction.openMessageContextActions(message, sourceNode, sourceRect, gesture)

View File

@ -2709,7 +2709,8 @@ final class StoryItemSetContainerSendMessage {
}
view.endEditing(true)
},
contentContext: self.progressPauseContext
contentContext: self.progressPauseContext,
progress: nil
)
}

View File

@ -677,16 +677,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return true
}
let controllerInteraction = ChatControllerInteraction(openMessage: { [weak self] message, mode in
let controllerInteraction = ChatControllerInteraction(openMessage: { [weak self] message, params in
guard let strongSelf = self, strongSelf.isNodeLoaded, let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(message.id) else {
return false
}
let mode = params.mode
let displayVoiceMessageDiscardAlert: () -> Bool = {
if strongSelf.presentVoiceMessageDiscardAlert(action: { [weak self] in
if let strongSelf = self {
Queue.mainQueue().after(0.1, {
let _ = strongSelf.controllerInteraction?.openMessage(message, mode)
let _ = strongSelf.controllerInteraction?.openMessage(message, params)
})
}
}, performAction: false) {
@ -736,6 +738,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
break
}
} else if let _ = media as? TelegramMediaGiveaway {
let progress = params.progress
let presentationData = strongSelf.presentationData
var signal = strongSelf.context.engine.payments.premiumGiveawayInfo(peerId: message.id.peerId, messageId: message.id)
let disposable: MetaDisposable
if let current = strongSelf.giveawayStatusDisposable {
@ -745,11 +750,26 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.giveawayStatusDisposable = disposable
}
let progressSignal = Signal<Never, NoError> { subscriber in
return EmptyDisposable
let progressSignal = Signal<Never, NoError> { [weak self] subscriber in
if let progress {
progress.set(.single(true))
return ActionDisposable {
Queue.mainQueue().async() {
progress.set(.single(false))
}
}
} else {
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
self?.present(controller, in: .window(.root))
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.15, queue: Queue.mainQueue())
|> delay(0.25, queue: Queue.mainQueue())
let progressDisposable = progressSignal.startStrict()
signal = signal
@ -950,7 +970,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.push(controller)
return true
case let .giftCode(slug, _, _, _, _):
strongSelf.openResolved(result: .premiumGiftCode(slug: slug), sourceMessageId: message.id)
strongSelf.openResolved(result: .premiumGiftCode(slug: slug), sourceMessageId: message.id, progress: params.progress)
return true
case let .suggestedProfilePhoto(image):
strongSelf.chatDisplayNode.dismissInput()
@ -3684,7 +3704,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if case let .visible(fraction, _) = itemNode.visibility, fraction > 0.7 {
action(Double(timestamp))
} else {
let _ = strongSelf.controllerInteraction?.openMessage(message, .timecode(Double(timestamp)))
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(Double(timestamp))))
}
found = true
}
@ -3696,7 +3716,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
messageId = sourceMessageId
}
if let message = strongSelf.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId) {
let _ = strongSelf.controllerInteraction?.openMessage(message, .timecode(Double(timestamp)))
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(Double(timestamp))))
} else {
strongSelf.navigateToMessage(messageLocation: .id(messageId, NavigateToMessageParams(timestamp: Double(timestamp), quote: nil)), animated: true, forceInCurrentChat: true)
}
@ -8077,12 +8097,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.scheduledScrollToMessageId = nil
if let timecode = params.timestamp, message.id == messageId {
Queue.mainQueue().after(0.2) {
let _ = strongSelf.controllerInteraction?.openMessage(message, .timecode(timecode))
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(timecode)))
}
}
} else if case let .message(_, _, maybeTimecode) = strongSelf.subject, let timecode = maybeTimecode, initial {
Queue.mainQueue().after(0.2) {
let _ = strongSelf.controllerInteraction?.openMessage(message, .timecode(timecode))
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(timecode)))
}
}
}
@ -12057,7 +12077,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var completed = false
self.chatDisplayNode.historyNode.forEachVisibleItemNode { itemNode in
if !completed, let itemNode = itemNode as? ChatMessageItemView, let message = itemNode.item?.message, let (_, soundEnabled, _, _, _) = itemNode.playMediaWithSound(), soundEnabled {
let _ = self.controllerInteraction?.openMessage(message, .landscape)
let _ = self.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .landscape))
completed = true
}
}
@ -14919,7 +14939,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let strongSelf = self, case let .result(info, _, _) = stickerPack {
strongSelf.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: file, loop: true, title: info.title, text: strongSelf.presentationData.strings.Stickers_PremiumPackInfoText, undoText: strongSelf.presentationData.strings.Stickers_PremiumPackView, customAction: nil), elevatedLayout: false, action: { [weak self] action in
if let strongSelf = self, action == .undo {
let _ = strongSelf.controllerInteraction?.openMessage(message, .default)
let _ = strongSelf.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .default))
}
return false
}), in: .current)
@ -15404,7 +15424,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.raiseToListenActivateRecordingTimer?.invalidate()
self.raiseToListenActivateRecordingTimer = nil
if let messageToListen = self.firstLoadedMessageToListen() {
let _ = self.controllerInteraction?.openMessage(messageToListen, .default)
let _ = self.controllerInteraction?.openMessage(messageToListen, OpenMessageParams(mode: .default))
} else {
let timeout = (self.voicePlaylistDidEndTimestamp + 1.0) - CACurrentMediaTime()
self.raiseToListenActivateRecordingTimer = SwiftSignalKit.Timer(timeout: max(0.0, timeout), repeat: false, completion: { [weak self] in
@ -16421,7 +16441,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if case let .id(_, params) = messageLocation, let timecode = params.timestamp {
let _ = self.controllerInteraction?.openMessage(message, .timecode(timecode))
let _ = self.controllerInteraction?.openMessage(message, OpenMessageParams(mode: .timecode(timecode)))
}
} else if case let .index(index) = messageLocation, index.id.id == 0, index.timestamp > 0, case .scheduledMessages = self.presentationInterfaceState.subject {
self.chatDisplayNode.historyNode.scrollToMessage(from: scrollFromIndex, to: index, animated: animated, scrollPosition: scrollPosition)
@ -17475,7 +17495,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}))
}
func openResolved(result: ResolvedUrl, sourceMessageId: MessageId?, forceExternal: Bool = false, concealed: Bool = false, commit: @escaping () -> Void = {}) {
func openResolved(result: ResolvedUrl, sourceMessageId: MessageId?, progress: Promise<Bool>? = nil, forceExternal: Bool = false, concealed: Bool = false, commit: @escaping () -> Void = {}) {
guard let peerId = self.chatLocation.peerId else {
return
}
@ -17485,13 +17505,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let dismissWebAppContollers: () -> Void = {
// if let currentWebAppController = strongSelf.currentWebAppController {
// strongSelf.currentWebAppController = nil
// currentWebAppController.dismiss(animated: true, completion: nil)
// } else if let currentWebAppController = strongSelf.currentMenuWebAppController {
// strongSelf.currentMenuWebAppController = nil
// currentWebAppController.dismiss(animated: true, completion: nil)
// }
}
switch navigation {
@ -17568,7 +17581,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, dismissInput: { [weak self] in
self?.chatDisplayNode.dismissInput()
}, contentContext: nil)
}, contentContext: nil, progress: progress)
}
func openUrl(_ url: String, concealed: Bool, forceExternal: Bool = false, skipUrlAuth: Bool = false, skipConcealedAlert: Bool = false, message: Message? = nil, allowInlineWebpageResolution: Bool = false, progress: Promise<Bool>? = nil, commit: @escaping () -> Void = {}) {
@ -17589,7 +17602,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else if content.file == nil, (content.image == nil || content.isMediaLargeByDefault == true || content.isMediaLargeByDefault == nil), let embedUrl = content.embedUrl, !embedUrl.isEmpty {
progress?.set(.single(false))
if let controllerInteraction = self.controllerInteraction {
if controllerInteraction.openMessage(message, .default) {
if controllerInteraction.openMessage(message, OpenMessageParams(mode: .default)) {
return
}
}

View File

@ -30,6 +30,7 @@ import ChatMessageItem
import ChatMessageItemImpl
import ChatMessageItemView
import ChatMessageTransitionNode
import ChatControllerInteraction
struct ChatTopVisibleMessageRange: Equatable {
var lowerBound: MessageIndex
@ -200,7 +201,7 @@ private func maxMessageIndexForEntries(_ view: ChatHistoryView, indexRange: (Int
extension ListMessageItemInteraction {
convenience init(controllerInteraction: ChatControllerInteraction) {
self.init(openMessage: { message, mode -> Bool in
return controllerInteraction.openMessage(message, mode)
return controllerInteraction.openMessage(message, OpenMessageParams(mode: mode))
}, openMessageContextMenu: { message, bool, node, rect, gesture in
controllerInteraction.openMessageContextMenu(message, bool, node, rect, gesture, nil)
}, toggleMessagesSelection: { messageId, selected in

View File

@ -1501,7 +1501,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.StickerPack_ViewPack, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Sticker"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
let _ = controllerInteraction.openMessage(message, .default)
let _ = controllerInteraction.openMessage(message, OpenMessageParams(mode: .default))
f(.dismissWithoutContent)
})))
}

View File

@ -48,7 +48,22 @@ private func defaultNavigationForPeerId(_ peerId: PeerId?, navigation: ChatContr
}
}
func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)? = nil, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?) {
func openResolvedUrlImpl(
_ resolvedUrl: ResolvedUrl,
context: AccountContext,
urlContext: OpenURLContext,
navigationController: NavigationController?,
forceExternal: Bool,
openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void,
sendFile: ((FileMediaReference) -> Void)?,
sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?,
requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)? = nil,
joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?,
present: @escaping (ViewController, Any?) -> Void,
dismissInput: @escaping () -> Void,
contentContext: Any?,
progress: Promise<Bool>?
) {
let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
if case let .chat(_, maybeUpdatedPresentationData) = urlContext {
updatedPresentationData = maybeUpdatedPresentationData
@ -890,7 +905,32 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
if let updatedPresentationData, updatedPresentationData.initial.theme.overallDarkAppearance {
forceDark = true
}
let _ = (context.engine.payments.checkPremiumGiftCode(slug: slug)
let progressSignal = Signal<Never, NoError> { subscriber in
if let progress {
progress.set(.single(true))
return ActionDisposable {
Queue.mainQueue().async() {
progress.set(.single(false))
}
}
} else {
return EmptyDisposable
}
}
|> runOn(Queue.mainQueue())
|> delay(0.25, queue: Queue.mainQueue())
let progressDisposable = progressSignal.startStrict()
var signal = context.engine.payments.checkPremiumGiftCode(slug: slug)
signal = signal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
let _ = (signal
|> deliverOnMainQueue).startStandalone(next: { [weak navigationController] giftCode in
if let giftCode {
var dismissImpl: (() -> Void)?

View File

@ -240,7 +240,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
context.sharedContext.applicationBindings.getWindowHost()?.present(c, on: .root, blockInteraction: false, completion: {})
}, dismissInput: {
dismissInput()
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}
}

View File

@ -2405,7 +2405,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
)
self._chatInterfaceInteraction = ChatControllerInteraction(openMessage: { [weak self] message, mode in
self._chatInterfaceInteraction = ChatControllerInteraction(openMessage: { [weak self] message, _ in
guard let strongSelf = self else {
return false
}
@ -4518,7 +4518,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
self?.controller?.present(c, in: .window(.root), with: a)
}, dismissInput: { [weak self] in
self?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}
private func openUrl(url: String, concealed: Bool, external: Bool, forceExternal: Bool = false, commit: @escaping () -> Void = {}) {
@ -4544,7 +4544,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
self?.controller?.present(c, in: .window(.root), with: a)
}, dismissInput: {
self?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
})
}
@ -5466,7 +5466,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
return
}
self.controller?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}, action: nil as ((ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void)?)))
c.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
@ -5655,7 +5655,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
return
}
self.controller?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}, action: nil as ((ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void)?)))
c.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
@ -5783,7 +5783,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
return
}
self.controller?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}, action: nil as ((ContextControllerProtocol, @escaping (ContextMenuActionResult) -> Void) -> Void)?)))
c.pushItems(items: .single(ContextController.Items(content: .list(subItems))))
@ -7056,7 +7056,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
controller?.present(c, in: .window(.root), with: a)
}, dismissInput: { [weak controller] in
controller?.view.endEditing(true)
}, contentContext: nil)
}, contentContext: nil, progress: nil)
}
private func performBotCommand(command: PeerInfoBotCommand) {
@ -8689,7 +8689,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
strongSelf.context.sharedContext.openResolvedUrl(resolvedUrl, context: strongSelf.context, urlContext: .generic, navigationController: strongSelf.controller?.navigationController as? NavigationController, forceExternal: false, openPeer: { peer, navigation in
}, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { [weak self] controller, arguments in
self?.controller?.push(controller)
}, dismissInput: {}, contentContext: nil)
}, dismissInput: {}, contentContext: nil, progress: nil)
}
})
}

View File

@ -834,7 +834,7 @@ final class PeerInfoGifPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDe
self._itemInteraction = VisualMediaItemInteraction(
openMessage: { [weak self] message in
let _ = self?.chatControllerInteraction.openMessage(message, .default)
let _ = self?.chatControllerInteraction.openMessage(message, OpenMessageParams(mode: .default))
},
openMessageContextActions: { [weak self] message, sourceNode, sourceRect, gesture in
self?.chatControllerInteraction.openMessageContextActions(message, sourceNode, sourceRect, gesture)

View File

@ -1416,8 +1416,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return resolveUrlImpl(context: context, peerId: peerId, url: url, skipUrlAuth: skipUrlAuth)
}
public func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)?, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?) {
openResolvedUrlImpl(resolvedUrl, context: context, urlContext: urlContext, navigationController: navigationController, forceExternal: forceExternal, openPeer: openPeer, sendFile: sendFile, sendSticker: sendSticker, requestMessageActionUrlAuth: requestMessageActionUrlAuth, joinVoiceChat: joinVoiceChat, present: present, dismissInput: dismissInput, contentContext: contentContext)
public func openResolvedUrl(_ resolvedUrl: ResolvedUrl, context: AccountContext, urlContext: OpenURLContext, navigationController: NavigationController?, forceExternal: Bool, openPeer: @escaping (EnginePeer, ChatControllerInteractionNavigateToPeer) -> Void, sendFile: ((FileMediaReference) -> Void)?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?, requestMessageActionUrlAuth: ((MessageActionUrlSubject) -> Void)?, joinVoiceChat: ((PeerId, String?, CachedChannelData.ActiveCall) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, contentContext: Any?, progress: Promise<Bool>?) {
openResolvedUrlImpl(resolvedUrl, context: context, urlContext: urlContext, navigationController: navigationController, forceExternal: forceExternal, openPeer: openPeer, sendFile: sendFile, sendSticker: sendSticker, requestMessageActionUrlAuth: requestMessageActionUrlAuth, joinVoiceChat: joinVoiceChat, present: present, dismissInput: dismissInput, contentContext: contentContext, progress: progress)
}
public func makeDeviceContactInfoController(context: AccountContext, subject: DeviceContactInfoSubject, completed: (() -> Void)?, cancelled: (() -> Void)?) -> ViewController {

View File

@ -54,7 +54,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
sendSticker: nil,
requestMessageActionUrlAuth: nil,
joinVoiceChat: nil,
present: presentImpl, dismissInput: {}, contentContext: nil)
present: presentImpl, dismissInput: {}, contentContext: nil, progress: nil)
}
let openLinkImpl: (String) -> Void = { [weak controller] url in
@ -94,7 +94,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
if let navigationController = controller.navigationController as? NavigationController {
openResolvedUrlImpl(result, context: context, urlContext: peerId.flatMap { .chat(peerId: $0, updatedPresentationData: nil) } ?? .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigateToPeer in
openResolvedPeerImpl(peer, navigateToPeer)
}, sendFile: nil, sendSticker: nil, joinVoiceChat: nil, present: { c, a in }, dismissInput: {}, contentContext: nil)
}, sendFile: nil, sendSticker: nil, joinVoiceChat: nil, present: { c, a in }, dismissInput: {}, contentContext: nil, progress: nil)
}
default:
break