mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Various improvements
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
import Foundation
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TextSelectionNode
|
||||
import Markdown
|
||||
import AppBundle
|
||||
import TextFormat
|
||||
import TextNodeWithEntities
|
||||
|
||||
private final class ContextActionsSelectionGestureRecognizer: UIPanGestureRecognizer {
|
||||
var updateLocation: ((CGPoint, Bool) -> Void)?
|
||||
@@ -340,17 +344,34 @@ private final class InnerActionsContainerNode: ASDisplayNode {
|
||||
final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
private let presentationData: PresentationData
|
||||
private var effectView: UIVisualEffectView?
|
||||
private let textNode: TextNode
|
||||
private let highlightBackgroundNode: ASDisplayNode
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
private let textNode: TextNodeWithEntities
|
||||
private var textSelectionNode: TextSelectionNode?
|
||||
private let iconNode: ASImageNode
|
||||
|
||||
private let text: String
|
||||
private var arguments: TextNodeWithEntities.Arguments?
|
||||
private var file: TelegramMediaFile?
|
||||
private let targetSelectionIndex: Int?
|
||||
|
||||
private var action: (() -> Void)?
|
||||
var requestDismiss: () -> Void = {}
|
||||
|
||||
init(presentationData: PresentationData, tip: ContextController.Tip) {
|
||||
self.presentationData = presentationData
|
||||
self.textNode = TextNode()
|
||||
|
||||
self.highlightBackgroundNode = ASDisplayNode()
|
||||
self.highlightBackgroundNode.isAccessibilityElement = false
|
||||
self.highlightBackgroundNode.alpha = 0.0
|
||||
|
||||
self.buttonNode = HighlightTrackingButtonNode()
|
||||
|
||||
self.textNode = TextNodeWithEntities()
|
||||
self.textNode.textNode.isUserInteractionEnabled = false
|
||||
self.textNode.textNode.displaysAsynchronously = true
|
||||
|
||||
var isUserInteractionEnabled = false
|
||||
var icon: UIImage?
|
||||
switch tip {
|
||||
case .textSelection:
|
||||
@@ -372,10 +393,14 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
self.text = isChannel ? self.presentationData.strings.Conversation_CopyProtectionInfoChannel : self.presentationData.strings.Conversation_CopyProtectionInfoGroup
|
||||
self.targetSelectionIndex = nil
|
||||
icon = UIImage(bundleImageName: "Chat/Context Menu/ReportCopyright")
|
||||
case let .animatedEmoji(packs):
|
||||
self.text = packs.count == 1 ? self.presentationData.strings.ChatContextMenu_EmojiSetSingle("name").string : self.presentationData.strings.ChatContextMenu_EmojiSet(Int32(packs.count))
|
||||
case let .animatedEmoji(text, arguments, file, action):
|
||||
self.action = action
|
||||
self.text = text ?? ""
|
||||
self.arguments = arguments
|
||||
self.file = file
|
||||
self.targetSelectionIndex = nil
|
||||
icon = UIImage(bundleImageName: "Chat/Context Menu/ReportCopyright")
|
||||
icon = nil //UIImage(bundleImageName: "Chat/Context Menu/Arrow")
|
||||
isUserInteractionEnabled = text != nil
|
||||
}
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
@@ -390,18 +415,43 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
|
||||
self.backgroundColor = presentationData.theme.contextMenu.backgroundColor
|
||||
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: presentationData.theme.contextMenu.primaryColor.withAlphaComponent(0.15), knob: presentationData.theme.contextMenu.primaryColor, knobDiameter: 8.0), strings: presentationData.strings, textNode: self.textNode, updateIsActive: { _ in
|
||||
let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: presentationData.theme.contextMenu.primaryColor.withAlphaComponent(0.15), knob: presentationData.theme.contextMenu.primaryColor, knobDiameter: 8.0), strings: presentationData.strings, textNode: self.textNode.textNode, updateIsActive: { _ in
|
||||
}, present: { _, _ in
|
||||
}, rootNode: self, performAction: { _, _ in
|
||||
})
|
||||
self.textSelectionNode = textSelectionNode
|
||||
|
||||
self.addSubnode(self.textNode)
|
||||
self.addSubnode(self.highlightBackgroundNode)
|
||||
self.addSubnode(self.textNode.textNode)
|
||||
self.addSubnode(self.iconNode)
|
||||
|
||||
self.textSelectionNode.flatMap(self.addSubnode)
|
||||
|
||||
self.addSubnode(textSelectionNode.highlightAreaNode)
|
||||
|
||||
self.addSubnode(self.buttonNode)
|
||||
|
||||
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if highlighted {
|
||||
strongSelf.highlightBackgroundNode.alpha = 1.0
|
||||
} else {
|
||||
let previousAlpha = strongSelf.highlightBackgroundNode.alpha
|
||||
strongSelf.highlightBackgroundNode.alpha = 0.0
|
||||
strongSelf.highlightBackgroundNode.layer.animateAlpha(from: previousAlpha, to: 0.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
self.buttonNode.addTarget(self, action: #selector(self.pressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.isUserInteractionEnabled = isUserInteractionEnabled
|
||||
}
|
||||
|
||||
@objc func pressed() {
|
||||
self.requestDismiss()
|
||||
self.action?()
|
||||
}
|
||||
|
||||
func updateLayout(widthClass: ContainerViewLayoutSizeClass, width: CGFloat, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
@@ -436,15 +486,37 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
let iconSideInset: CGFloat = 12.0
|
||||
|
||||
let textFont = Font.regular(floor(presentationData.listsFontSize.baseDisplaySize * 14.0 / 17.0))
|
||||
let boldTextFont = Font.bold(floor(presentationData.listsFontSize.baseDisplaySize * 14.0 / 17.0))
|
||||
let textColor = self.presentationData.theme.contextMenu.primaryColor
|
||||
let accentColor = self.presentationData.theme.contextMenu.badgeFillColor
|
||||
|
||||
let iconSize = self.iconNode.image?.size ?? CGSize(width: 16.0, height: 16.0)
|
||||
|
||||
let text = self.text.replacingOccurrences(of: "#", with: "# ")
|
||||
let attributedText = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: textColor), bold: MarkdownAttributeSet(font: boldTextFont, textColor: textColor), link: MarkdownAttributeSet(font: boldTextFont, textColor: accentColor), linkAttribute: { _ in
|
||||
return nil
|
||||
})))
|
||||
if let file = self.file {
|
||||
let range = (attributedText.string as NSString).range(of: "#")
|
||||
if range.location != NSNotFound {
|
||||
attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(stickerPack: nil, fileId: file.fileId.id, file: file), range: range)
|
||||
}
|
||||
}
|
||||
|
||||
let makeTextLayout = TextNode.asyncLayout(self.textNode)
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: self.text, font: textFont, textColor: self.presentationData.theme.contextMenu.primaryColor), backgroundColor: nil, minimumNumberOfLines: 0, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - horizontalInset * 2.0 - iconSize.width - 8.0, height: .greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets(), lineColor: nil, textShadowColor: nil, textStroke: nil))
|
||||
let _ = textApply()
|
||||
let shimmeringForegroundColor: UIColor
|
||||
if presentationData.theme.overallDarkAppearance {
|
||||
let backgroundColor = presentationData.theme.contextMenu.backgroundColor.blitOver(presentationData.theme.list.plainBackgroundColor, alpha: 1.0)
|
||||
shimmeringForegroundColor = presentationData.theme.contextMenu.primaryColor.blitOver(backgroundColor, alpha: 0.1)
|
||||
} else {
|
||||
shimmeringForegroundColor = presentationData.theme.contextMenu.primaryColor.withMultipliedAlpha(0.07)
|
||||
}
|
||||
|
||||
let makeTextLayout = TextNodeWithEntities.asyncLayout(self.textNode)
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedText, backgroundColor: nil, minimumNumberOfLines: 0, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - horizontalInset * 2.0 - iconSize.width - 8.0, height: .greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets(), lineColor: nil, textShadowColor: nil, textStroke: nil))
|
||||
let _ = textApply(self.arguments?.withUpdatedPlaceholderColor(shimmeringForegroundColor))
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: horizontalInset, y: verticalInset), size: textLayout.size)
|
||||
transition.updateFrame(node: self.textNode, frame: textFrame)
|
||||
transition.updateFrame(node: self.textNode.textNode, frame: textFrame)
|
||||
|
||||
let size = CGSize(width: width, height: textLayout.size.height + verticalInset * 2.0)
|
||||
|
||||
@@ -460,6 +532,10 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
||||
transition.updateFrame(view: effectView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
}
|
||||
|
||||
self.highlightBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor
|
||||
self.highlightBackgroundNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
@@ -536,7 +612,9 @@ final class ContextActionsContainerNode: ASDisplayNode {
|
||||
self.actionsNode = InnerActionsContainerNode(presentationData: presentationData, items: itemList, getController: getController, actionSelected: actionSelected, requestLayout: requestLayout, feedbackTap: feedbackTap, blurBackground: blurBackground)
|
||||
if let tip = items.tip {
|
||||
let textSelectionTipNode = InnerTextSelectionTipContainerNode(presentationData: presentationData, tip: tip)
|
||||
textSelectionTipNode.isUserInteractionEnabled = false
|
||||
textSelectionTipNode.requestDismiss = {
|
||||
getController()?.dismiss(completion: nil)
|
||||
}
|
||||
self.textSelectionTipNode = textSelectionTipNode
|
||||
} else {
|
||||
self.textSelectionTipNode = nil
|
||||
|
||||
Reference in New Issue
Block a user