Add spoilers to ImmediateTextWithEntitiesNode

This commit is contained in:
Ilya Laktyushin 2023-03-09 20:20:51 +04:00
parent 05c3ae3ae0
commit 39cf99e1db
5 changed files with 33 additions and 19 deletions

View File

@ -336,6 +336,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
self.textNode = ImmediateTextNodeWithEntities()
self.textNode.maximumNumberOfLines = 0
self.textNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)
self.textNode.displaySpoilerEffect = false
self.authorNameNode = ASTextNode()
self.authorNameNode.maximumNumberOfLines = 1
@ -802,6 +803,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
if self.spoilerTextNode == nil {
let spoilerTextNode = ImmediateTextNodeWithEntities()
spoilerTextNode.displaySpoilerEffect = false
spoilerTextNode.attributedText = textNode.attributedText
spoilerTextNode.maximumNumberOfLines = 0
spoilerTextNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)

View File

@ -1145,7 +1145,7 @@ private final class PremiumGiftContext: AttachmentMediaPickerContext {
func setCaption(_ caption: NSAttributedString) {
}
func send(silently: Bool, mode: AttachmentMediaPickerSendMode) {
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode) {
}
func schedule() {

View File

@ -17,6 +17,7 @@ swift_library(
"//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
"//submodules/TelegramUI/Components/AnimationCache:AnimationCache",
"//submodules/TelegramUI/Components/MultiAnimationRenderer:MultiAnimationRenderer",
"//submodules/InvisibleInkDustNode:InvisibleInkDustNode",
],
visibility = [
"//visibility:public",

View File

@ -8,6 +8,7 @@ import AccountContext
import AnimationCache
import MultiAnimationRenderer
import TelegramCore
import InvisibleInkDustNode
private extension CGRect {
var center: CGPoint {
@ -287,12 +288,15 @@ public class ImmediateTextNodeWithEntities: TextNode {
public var textStroke: (UIColor, CGFloat)?
public var cutout: TextNodeCutout?
public var displaySpoilers = false
public var displaySpoilerEffect = true
public var spoilerColor: UIColor = .black
private var enableLooping: Bool = true
public var arguments: TextNodeWithEntities.Arguments?
private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayer] = [:]
private var dustNode: InvisibleInkDustNode?
public var visibility: Bool = false {
didSet {
@ -337,7 +341,7 @@ public class ImmediateTextNodeWithEntities: TextNode {
public var linkHighlightColor: UIColor?
public var trailingLineWidth: CGFloat?
var constrainedSize: CGSize?
public var highlightAttributeAction: (([NSAttributedString.Key: Any]) -> NSAttributedString.Key?)? {
@ -378,9 +382,12 @@ public class ImmediateTextNodeWithEntities: TextNode {
let _ = apply()
var enableAnimations = true
if let arguments = self.arguments {
self.updateInlineStickers(context: arguments.context, cache: arguments.cache, renderer: arguments.renderer, textLayout: layout, placeholderColor: arguments.placeholderColor)
enableAnimations = arguments.context.sharedContext.energyUsageSettings.fullTranslucency
}
self.updateSpoilers(enableAnimations: enableAnimations, textLayout: layout)
if layout.numberOfLines > 1 {
self.trailingLineWidth = layout.trailingLineWidth
@ -443,6 +450,25 @@ public class ImmediateTextNodeWithEntities: TextNode {
}
}
private func updateSpoilers(enableAnimations: Bool, textLayout: TextNodeLayout) {
if !textLayout.spoilers.isEmpty && self.displaySpoilerEffect {
if self.dustNode == nil {
let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: enableAnimations)
self.dustNode = dustNode
self.addSubnode(dustNode)
}
if let dustNode = self.dustNode {
let textFrame = CGRect(origin: .zero, size: textLayout.size)
dustNode.update(size: textFrame.size, color: self.spoilerColor, textColor: self.spoilerColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
}
} else if let dustNode = self.dustNode {
self.dustNode = nil
dustNode.removeFromSupernode()
}
}
public func updateLayoutInfo(_ constrainedSize: CGSize) -> ImmediateTextNodeLayoutInfo {
self.constrainedSize = constrainedSize

View File

@ -11,7 +11,6 @@ import AccountContext
import LocalizedPeerData
import PhotoResources
import TelegramStringFormatting
import InvisibleInkDustNode
import TextFormat
import ChatPresentationInterfaceState
import TextNodeWithEntities
@ -29,7 +28,6 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
let iconNode: ASImageNode
let titleNode: ImmediateTextNode
let textNode: ImmediateTextNodeWithEntities
var dustNode: InvisibleInkDustNode?
let imageNode: TransformImageNode
private let actionArea: AccessibilityAreaNode
@ -73,6 +71,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
self.textNode.displaysAsynchronously = false
self.textNode.insets = UIEdgeInsets(top: 3.0, left: 0.0, bottom: 3.0, right: 0.0)
self.textNode.visibility = true
self.textNode.spoilerColor = self.theme.chat.inputPanel.secondaryTextColor
if let animationCache = animationCache, let animationRenderer = animationRenderer {
self.textNode.arguments = TextNodeWithEntities.Arguments(
@ -293,6 +292,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
if let text = self.textNode.attributedText?.string {
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(15.0), textColor: self.theme.chat.inputPanel.primaryTextColor)
}
self.textNode.spoilerColor = self.theme.chat.inputPanel.secondaryTextColor
if let (size, inset, interfaceState) = self.validLayout {
self.updateState(size: size, inset: inset, interfaceState: interfaceState)
@ -345,21 +345,6 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
if self.textNode.supernode == self {
self.textNode.frame = textFrame
}
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
if self.dustNode == nil {
let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
self.dustNode = dustNode
self.textNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.textNode)
}
if let dustNode = self.dustNode {
dustNode.update(size: textFrame.size, color: self.theme.chat.inputPanel.secondaryTextColor, textColor: self.theme.chat.inputPanel.primaryTextColor, rects: textLayout.spoilers.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) }, wordRects: textLayout.spoilerWords.map { $0.1.offsetBy(dx: 3.0, dy: 3.0).insetBy(dx: 1.0, dy: 1.0) })
dustNode.frame = textFrame.insetBy(dx: -3.0, dy: -3.0).offsetBy(dx: 0.0, dy: 3.0)
}
} else if let dustNode = self.dustNode {
self.dustNode = nil
dustNode.removeFromSupernode()
}
}
@objc func closePressed() {