Various improvements

This commit is contained in:
Ilya Laktyushin 2024-06-23 19:05:01 +04:00
parent 63d380a534
commit 813a913bca
12 changed files with 133 additions and 420 deletions

View File

@ -10629,6 +10629,7 @@ Sorry for the inconvenience.";
"MediaEditor.Shortcut.Location" = "Location";
"MediaEditor.Shortcut.Reaction" = "Reaction";
"MediaEditor.Shortcut.Audio" = "Audio";
"MediaEditor.Shortcut.Link" = "Link";
"BoostGift.AdditionalPrizes" = "Additional Prizes";
"BoostGift.AdditionalPrizesPlaceholder" = "Enter Your Prize";
@ -12431,3 +12432,5 @@ Sorry for the inconvenience.";
"Premium.MessageEffects" = "Message Effects";
"Premium.MessageEffectsInfo" = "Add over 500 animated effects to private messages.";
"Chat.UnlockMedia" = "Unlock for %@";

View File

@ -1044,8 +1044,7 @@ final class ChatSendMessageContextScreenComponent: Component {
self.animateOutToEmpty = true
self.environment?.controller()?.dismiss()
//TODO:localize
let premiumController = component.context.sharedContext.makePremiumIntroController(context: component.context, source: .animatedEmoji, forceDark: false, dismissed: nil)
let premiumController = component.context.sharedContext.makePremiumIntroController(context: component.context, source: .messageEffects, forceDark: false, dismissed: nil)
component.openPremiumPaywall(premiumController)
}
return false

View File

@ -512,7 +512,6 @@ final class PriceNode: ASDisplayNode {
var backgroundTransition = transition
let labelTransition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut)
if let price {
//TODO:localize
self.labelNode.attributedText = NSAttributedString(string: "\(price)", font: Font.semibold(15.0), textColor: .white)
labelSize = self.labelNode.updateLayout(CGSize(width: 240.0, height: 50.0))

View File

@ -826,7 +826,6 @@ public class PremiumLimitsListScreen: ViewController {
)
)
)
//TODO:localize
availableItems[.messageEffects] = DemoPagerComponent.Item(
AnyComponentWithIdentity(
id: PremiumDemoScreen.Subject.messageEffects,

View File

@ -477,25 +477,22 @@ public final class ChatBotInfoItemNode: ListViewItemNode {
case .longTap, .doubleTap:
if let item = self.item, self.backgroundNode.frame.contains(location) {
let tapAction = self.tapActionAtPoint(location, gesture: gesture, isEstimating: false)
//TODO:do
let _ = item
let _ = tapAction
// switch tapAction.content {
// case .none, .ignore:
// break
// case let .url(url):
// item.controllerInteraction.longTap(.url(url.url), nil)
// case let .peerMention(peerId, mention, _):
// item.controllerInteraction.longTap(.peerMention(peerId, mention), nil)
// case let .textMention(name):
// item.controllerInteraction.longTap(.mention(name), nil)
// case let .botCommand(command):
// item.controllerInteraction.longTap(.command(command), nil)
// case let .hashtag(_, hashtag):
// item.controllerInteraction.longTap(.hashtag(hashtag), nil)
// default:
// break
// }
switch tapAction.content {
case .none, .ignore:
break
case let .url(url):
item.controllerInteraction.longTap(.url(url.url), ChatControllerInteraction.LongTapParams())
case let .peerMention(peerId, mention, _):
item.controllerInteraction.longTap(.peerMention(peerId, mention), ChatControllerInteraction.LongTapParams())
case let .textMention(name):
item.controllerInteraction.longTap(.mention(name), ChatControllerInteraction.LongTapParams())
case let .botCommand(command):
item.controllerInteraction.longTap(.command(command), ChatControllerInteraction.LongTapParams())
case let .hashtag(_, hashtag):
item.controllerInteraction.longTap(.hashtag(hashtag), ChatControllerInteraction.LongTapParams())
default:
break
}
}
default:
break

View File

@ -2864,7 +2864,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let mosaicRange = mosaicRange, mosaicRange.contains(i), let (framesAndPositions, size) = calculatedGroupFramesAndSize {
let mosaicIndex = i - mosaicRange.lowerBound
if mosaicIndex == 0 {
if mosaicIndex == 0 && i == 0 {
if !headerSize.height.isZero {
contentNodesHeight += 7.0
totalContentNodesHeight += 7.0

View File

@ -80,24 +80,6 @@ public class ChatMessageUnlockMediaNode: ASDisplayNode {
self.addSubnode(self.contentNode)
self.contentNode.addSubnode(self.backgroundNode)
// self.contentNode.highligthedChanged = { [weak self] highlighted in
// if let strongSelf = self {
// if highlighted, !strongSelf.frame.width.isZero {
// let scale = (strongSelf.frame.width - 10.0) / strongSelf.frame.width
//
// strongSelf.contentNode.layer.animateScale(from: 1.0, to: scale, duration: 0.15, removeOnCompletion: false)
//
// strongSelf.backgroundNode.layer.removeAnimation(forKey: "opacity")
// strongSelf.backgroundNode.alpha = 0.2
// } else if let presentationLayer = strongSelf.contentNode.layer.presentation() {
// strongSelf.contentNode.layer.animateScale(from: CGFloat((presentationLayer.value(forKeyPath: "transform.scale.y") as? NSNumber)?.floatValue ?? 1.0), to: 1.0, duration: 0.25, removeOnCompletion: false)
//
// strongSelf.backgroundNode.alpha = 1.0
// strongSelf.backgroundNode.layer.animateAlpha(from: 0.2, to: 1.0, duration: 0.2)
// }
// }
// }
self.contentNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
}
@ -113,8 +95,7 @@ public class ChatMessageUnlockMediaNode: ASDisplayNode {
let textFont = Font.medium(fontSize)
let padding: CGFloat = 10.0
//TODO:localize
let text = NSMutableAttributedString(string: "Unlock for ⭐️ \(arguments.media.amount)", font: textFont, textColor: .white)
let text = NSMutableAttributedString(string: arguments.presentationData.strings.Chat_UnlockMedia("⭐️ \(arguments.media.amount)").string, font: textFont, textColor: .white)
if let range = text.string.range(of: "⭐️") {
text.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: text.string))
text.addAttribute(.baselineOffset, value: 0.5, range: NSRange(range, in: text.string))

View File

@ -158,7 +158,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
public var messageNode: ASDisplayNode?
public var progress: Promise<Bool>?
public init(message: Message?, contentNode: ContextExtractedContentContainingNode? = nil, messageNode: ASDisplayNode? = nil, progress: Promise<Bool>? = nil) {
public init(message: Message? = nil, contentNode: ContextExtractedContentContainingNode? = nil, messageNode: ASDisplayNode? = nil, progress: Promise<Bool>? = nil) {
self.message = message
self.contentNode = contentNode
self.messageNode = messageNode

View File

@ -5750,14 +5750,15 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
self?.node.presentGallery()
})))
//TODO:localize
items.append(.action(ContextMenuActionItem(text: "Link", icon: { theme in
if self.context.isPremium {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaEditor_Shortcut_Link, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, a in
a(.default)
self?.node.addOrEditLink()
})))
}
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaEditor_Shortcut_Location, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Media Editor/LocationSmall"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, a in

View File

@ -33,7 +33,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
let openPeer: (EnginePeer) -> Void
let openMessage: (EngineMessage.Id) -> Void
let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void
let copyTransactionId: () -> Void
let copyTransactionId: (String) -> Void
init(
context: AccountContext,
@ -43,7 +43,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
openPeer: @escaping (EnginePeer) -> Void,
openMessage: @escaping (EngineMessage.Id) -> Void,
openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void,
copyTransactionId: @escaping () -> Void
copyTransactionId: @escaping (String) -> Void
) {
self.context = context
self.subject = subject
@ -464,7 +464,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
)
),
action: {
component.copyTransactionId()
component.copyTransactionId(transactionId)
}
)
),
@ -650,7 +650,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
let openPeer: (EnginePeer) -> Void
let openMessage: (EngineMessage.Id) -> Void
let openMedia: ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void
let copyTransactionId: () -> Void
let copyTransactionId: (String) -> Void
init(
context: AccountContext,
@ -659,7 +659,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
openPeer: @escaping (EnginePeer) -> Void,
openMessage: @escaping (EngineMessage.Id) -> Void,
openMedia: @escaping ([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void,
copyTransactionId: @escaping () -> Void
copyTransactionId: @escaping (String) -> Void
) {
self.context = context
self.subject = subject
@ -799,7 +799,7 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
var openPeerImpl: ((EnginePeer) -> Void)?
var openMessageImpl: ((EngineMessage.Id) -> Void)?
var openMediaImpl: (([Media], @escaping (Media) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))?, @escaping (UIView) -> Void) -> Void)?
var copyTransactionIdImpl: (() -> Void)?
var copyTransactionIdImpl: ((String) -> Void)?
super.init(
context: context,
component: StarsTransactionSheetComponent(
@ -815,8 +815,8 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
openMedia: { media, transitionNode, addToTransitionSurface in
openMediaImpl?(media, transitionNode, addToTransitionSurface)
},
copyTransactionId: {
copyTransactionIdImpl?()
copyTransactionId: { transactionId in
copyTransactionIdImpl?(transactionId)
}
),
navigationBarAppearance: .none,
@ -902,10 +902,12 @@ public class StarsTransactionScreen: ViewControllerComponentContainer {
}))
}
copyTransactionIdImpl = { [weak self] in
copyTransactionIdImpl = { [weak self] transactionId in
guard let self else {
return
}
UIPasteboard.general.string = transactionId
self.dismissAllTooltips()
let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -19,6 +19,95 @@ import SafariServices
extension ChatControllerImpl {
func openLinkContextMenu(url: String, params: ChatControllerInteraction.LongTapParams) -> Void {
guard let message = params.message, let contentNode = params.contentNode else {
var (cleanUrl, _) = parseUrl(url: url, wasConcealed: false)
var canAddToReadingList = true
var canOpenIn = availableOpenInOptions(context: self.context, item: .url(url: url)).count > 1
let mailtoString = "mailto:"
let telString = "tel:"
var openText = self.presentationData.strings.Conversation_LinkDialogOpen
var phoneNumber: String?
var isPhoneNumber = false
var isEmail = false
var hasOpenAction = true
if cleanUrl.hasPrefix(mailtoString) {
canAddToReadingList = false
cleanUrl = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: mailtoString.distance(from: mailtoString.startIndex, to: mailtoString.endIndex))...])
isEmail = true
} else if cleanUrl.hasPrefix(telString) {
canAddToReadingList = false
phoneNumber = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: telString.distance(from: telString.startIndex, to: telString.endIndex))...])
cleanUrl = phoneNumber!
openText = self.presentationData.strings.UserInfo_PhoneCall
canOpenIn = false
isPhoneNumber = true
if cleanUrl.hasPrefix("+888") {
hasOpenAction = false
}
} else if canOpenIn {
openText = self.presentationData.strings.Conversation_FileOpenIn
}
let actionSheet = ActionSheetController(presentationData: self.presentationData)
var items: [ActionSheetItem] = []
items.append(ActionSheetTextItem(title: cleanUrl))
if hasOpenAction {
items.append(ActionSheetButtonItem(title: openText, color: .accent, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
if canOpenIn {
strongSelf.openUrlIn(url)
} else {
strongSelf.openUrl(url, concealed: false)
}
}
}))
}
if let phoneNumber = phoneNumber {
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_AddContact, color: .accent, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated()
if let strongSelf = self {
strongSelf.controllerInteraction?.addContact(phoneNumber)
}
}))
}
items.append(ActionSheetButtonItem(title: canAddToReadingList ? self.presentationData.strings.ShareMenu_CopyShareLink : self.presentationData.strings.Conversation_ContextMenuCopy, color: .accent, action: { [weak actionSheet, weak self] in
actionSheet?.dismissAnimated()
guard let self else {
return
}
UIPasteboard.general.string = cleanUrl
let content: UndoOverlayContent
if isPhoneNumber {
content = .copy(text: self.presentationData.strings.Conversation_PhoneCopied)
} else if isEmail {
content = .copy(text: self.presentationData.strings.Conversation_EmailCopied)
} else if canAddToReadingList {
content = .linkCopied(text: self.presentationData.strings.Conversation_LinkCopied)
} else {
content = .copy(text: self.presentationData.strings.Conversation_TextCopied)
}
self.present(UndoOverlayController(presentationData: self.presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}))
if canAddToReadingList {
items.append(ActionSheetButtonItem(title: self.presentationData.strings.Conversation_AddToReadingList, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
if let link = URL(string: url) {
let _ = try? SSReadingList.default()?.addItem(with: link, title: nil, previewText: nil)
}
}))
}
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
self.chatDisplayNode.dismissInput()
self.present(actionSheet, in: .window(.root))
return
}

View File

@ -38,360 +38,3 @@ extension ChatControllerImpl {
}
}
}
//if let strongSelf = self {
// let presentationData = strongSelf.presentationData
// switch action {
// case let .url(url):
// var (cleanUrl, _) = parseUrl(url: url, wasConcealed: false)
// var canAddToReadingList = true
// var canOpenIn = availableOpenInOptions(context: strongSelf.context, item: .url(url: url)).count > 1
// let mailtoString = "mailto:"
// let telString = "tel:"
// var openText = strongSelf.presentationData.strings.Conversation_LinkDialogOpen
// var phoneNumber: String?
//
// var isPhoneNumber = false
// var isEmail = false
// var hasOpenAction = true
//
// if cleanUrl.hasPrefix(mailtoString) {
// canAddToReadingList = false
// cleanUrl = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: mailtoString.distance(from: mailtoString.startIndex, to: mailtoString.endIndex))...])
// isEmail = true
// } else if cleanUrl.hasPrefix(telString) {
// canAddToReadingList = false
// phoneNumber = String(cleanUrl[cleanUrl.index(cleanUrl.startIndex, offsetBy: telString.distance(from: telString.startIndex, to: telString.endIndex))...])
// cleanUrl = phoneNumber!
// openText = strongSelf.presentationData.strings.UserInfo_PhoneCall
// canOpenIn = false
// isPhoneNumber = true
//
// if cleanUrl.hasPrefix("+888") {
// hasOpenAction = false
// }
// } else if canOpenIn {
// openText = strongSelf.presentationData.strings.Conversation_FileOpenIn
// }
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
//
// var items: [ActionSheetItem] = []
// items.append(ActionSheetTextItem(title: cleanUrl))
// if hasOpenAction {
// items.append(ActionSheetButtonItem(title: openText, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// if canOpenIn {
// strongSelf.openUrlIn(url)
// } else {
// strongSelf.openUrl(url, concealed: false)
// }
// }
// }))
// }
// if let phoneNumber = phoneNumber {
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_AddContact, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.controllerInteraction?.addContact(phoneNumber)
// }
// }))
// }
// items.append(ActionSheetButtonItem(title: canAddToReadingList ? strongSelf.presentationData.strings.ShareMenu_CopyShareLink : strongSelf.presentationData.strings.Conversation_ContextMenuCopy, color: .accent, action: { [weak actionSheet, weak self] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = cleanUrl
//
// let content: UndoOverlayContent
// if isPhoneNumber {
// content = .copy(text: presentationData.strings.Conversation_PhoneCopied)
// } else if isEmail {
// content = .copy(text: presentationData.strings.Conversation_EmailCopied)
// } else if canAddToReadingList {
// content = .linkCopied(text: presentationData.strings.Conversation_LinkCopied)
// } else {
// content = .copy(text: presentationData.strings.Conversation_TextCopied)
// }
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }))
// if canAddToReadingList {
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_AddToReadingList, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let link = URL(string: url) {
// let _ = try? SSReadingList.default()?.addItem(with: link, title: nil, previewText: nil)
// }
// }))
// }
// actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .peerMention(peerId, mention):
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
// var items: [ActionSheetItem] = []
// if !mention.isEmpty {
// items.append(ActionSheetTextItem(title: mention))
// }
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
// |> deliverOnMainQueue).startStandalone(next: { peer in
// if let strongSelf = self, let peer = peer {
// strongSelf.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil)
// }
// })
// }
// }))
// if !mention.isEmpty {
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = mention
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_TextCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }))
// }
// actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .mention(mention):
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
// actionSheet.setItemGroups([ActionSheetItemGroup(items: [
// ActionSheetTextItem(title: mention),
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.openPeerMention(mention, sourceMessageId: message?.id)
// }
// }),
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = mention
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_UsernameCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// })
// ]), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .command(command):
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
// var items: [ActionSheetItem] = []
// items.append(ActionSheetTextItem(title: command))
// if canSendMessagesToChat(strongSelf.presentationInterfaceState) {
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.ShareMenu_Send, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.sendMessages([.message(text: command, attributes: [], inlineStickers: [:], mediaReference: nil, threadId: strongSelf.chatLocation.threadId, replyToMessageId: nil, replyToStoryId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])])
// }
// }))
// }
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = command
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_TextCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }))
// actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .hashtag(hashtag):
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
// actionSheet.setItemGroups([ActionSheetItemGroup(items: [
// ActionSheetTextItem(title: hashtag),
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.openHashtag(hashtag, peerName: nil)
// }
// }),
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = hashtag
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_HashtagCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// })
// ]), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .timecode(timecode, text):
// guard let message = message else {
// return
// }
//
// let context = strongSelf.context
// let chatPresentationInterfaceState = strongSelf.presentationInterfaceState
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
//
// var isCopyLink = false
// var isForward = false
// if message.id.namespace == Namespaces.Message.Cloud, let _ = message.peers[message.id.peerId] as? TelegramChannel, !(message.media.first is TelegramMediaAction) {
// isCopyLink = true
// } else if let forwardInfo = message.forwardInfo, let _ = forwardInfo.author as? TelegramChannel {
// isCopyLink = true
// isForward = true
// }
//
// actionSheet.setItemGroups([ActionSheetItemGroup(items: [
// ActionSheetTextItem(title: text),
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.controllerInteraction?.seekToTimecode(message, timecode, true)
// }
// }),
// ActionSheetButtonItem(title: isCopyLink ? strongSelf.presentationData.strings.Conversation_ContextMenuCopyLink : strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
//
// var messageId = message.id
// var channel = message.peers[message.id.peerId]
// if isForward, let forwardMessageId = message.forwardInfo?.sourceMessageId, let forwardAuthor = message.forwardInfo?.author as? TelegramChannel {
// messageId = forwardMessageId
// channel = forwardAuthor
// }
//
// if isCopyLink, let channel = channel as? TelegramChannel {
// var threadId: Int64?
//
// if case let .replyThread(replyThreadMessage) = chatPresentationInterfaceState.chatLocation {
// threadId = replyThreadMessage.threadId
// }
// let _ = (context.engine.messages.exportMessageLink(peerId: messageId.peerId, messageId: messageId, isThread: threadId != nil)
// |> map { result -> String? in
// return result
// }
// |> deliverOnMainQueue).startStandalone(next: { link in
// if let link = link {
// UIPasteboard.general.string = link + "?t=\(Int32(timecode))"
//
// let presentationData = context.sharedContext.currentPresentationData.with { $0 }
//
// var warnAboutPrivate = false
// if case .peer = chatPresentationInterfaceState.chatLocation {
// if channel.addressName == nil {
// warnAboutPrivate = true
// }
// }
// Queue.mainQueue().after(0.2, {
// let content: UndoOverlayContent
// if warnAboutPrivate {
// content = .linkCopied(text: presentationData.strings.Conversation_PrivateMessageLinkCopiedLong)
// } else {
// content = .linkCopied(text: presentationData.strings.Conversation_LinkCopied)
// }
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// })
// } else {
// UIPasteboard.general.string = text
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_TextCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }
// })
// } else {
// UIPasteboard.general.string = text
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_TextCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }
// })
// ]), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.chatDisplayNode.dismissInput()
// strongSelf.present(actionSheet, in: .window(.root))
// case let .bankCard(number):
// guard let message = message else {
// return
// }
//
// var signal = strongSelf.context.engine.payments.getBankCardInfo(cardNumber: number)
// let disposable: MetaDisposable
// if let current = strongSelf.bankCardDisposable {
// disposable = current
// } else {
// disposable = MetaDisposable()
// strongSelf.bankCardDisposable = disposable
// }
//
// var cancelImpl: (() -> Void)?
// let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
// let progressSignal = Signal<Never, NoError> { subscriber in
// let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
// cancelImpl?()
// }))
// strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
// return ActionDisposable { [weak controller] in
// Queue.mainQueue().async() {
// controller?.dismiss()
// }
// }
// }
// |> runOn(Queue.mainQueue())
// |> delay(0.15, queue: Queue.mainQueue())
// let progressDisposable = progressSignal.startStrict()
//
// signal = signal
// |> afterDisposed {
// Queue.mainQueue().async {
// progressDisposable.dispose()
// }
// }
// cancelImpl = {
// disposable.set(nil)
// }
// disposable.set((signal
// |> deliverOnMainQueue).startStrict(next: { [weak self] info in
// if let strongSelf = self, let info = info {
// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
// var items: [ActionSheetItem] = []
// items.append(ActionSheetTextItem(title: info.title))
// for url in info.urls {
// items.append(ActionSheetButtonItem(title: url.title, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// if let strongSelf = self {
// strongSelf.controllerInteraction?.openUrl(ChatControllerInteraction.OpenUrl(url: url.url, concealed: false, external: false, message: message))
// }
// }))
// }
// items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// UIPasteboard.general.string = number
//
// let content: UndoOverlayContent = .copy(text: presentationData.strings.Conversation_CardNumberCopied)
// self?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
// }))
// actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
// ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
// actionSheet?.dismissAnimated()
// })
// ])])
// strongSelf.present(actionSheet, in: .window(.root))
// }
// }))
//
// strongSelf.chatDisplayNode.dismissInput()
// }