mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Add spoilers to ImmediateTextWithEntitiesNode
This commit is contained in:
@@ -336,6 +336,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
|||||||
self.textNode = ImmediateTextNodeWithEntities()
|
self.textNode = ImmediateTextNodeWithEntities()
|
||||||
self.textNode.maximumNumberOfLines = 0
|
self.textNode.maximumNumberOfLines = 0
|
||||||
self.textNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)
|
self.textNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)
|
||||||
|
self.textNode.displaySpoilerEffect = false
|
||||||
|
|
||||||
self.authorNameNode = ASTextNode()
|
self.authorNameNode = ASTextNode()
|
||||||
self.authorNameNode.maximumNumberOfLines = 1
|
self.authorNameNode.maximumNumberOfLines = 1
|
||||||
@@ -802,6 +803,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
|||||||
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
||||||
if self.spoilerTextNode == nil {
|
if self.spoilerTextNode == nil {
|
||||||
let spoilerTextNode = ImmediateTextNodeWithEntities()
|
let spoilerTextNode = ImmediateTextNodeWithEntities()
|
||||||
|
spoilerTextNode.displaySpoilerEffect = false
|
||||||
spoilerTextNode.attributedText = textNode.attributedText
|
spoilerTextNode.attributedText = textNode.attributedText
|
||||||
spoilerTextNode.maximumNumberOfLines = 0
|
spoilerTextNode.maximumNumberOfLines = 0
|
||||||
spoilerTextNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)
|
spoilerTextNode.linkHighlightColor = UIColor(rgb: 0x5ac8fa, alpha: 0.2)
|
||||||
|
|||||||
@@ -1145,7 +1145,7 @@ private final class PremiumGiftContext: AttachmentMediaPickerContext {
|
|||||||
func setCaption(_ caption: NSAttributedString) {
|
func setCaption(_ caption: NSAttributedString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func send(silently: Bool, mode: AttachmentMediaPickerSendMode) {
|
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func schedule() {
|
func schedule() {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
|
"//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView",
|
||||||
"//submodules/TelegramUI/Components/AnimationCache:AnimationCache",
|
"//submodules/TelegramUI/Components/AnimationCache:AnimationCache",
|
||||||
"//submodules/TelegramUI/Components/MultiAnimationRenderer:MultiAnimationRenderer",
|
"//submodules/TelegramUI/Components/MultiAnimationRenderer:MultiAnimationRenderer",
|
||||||
|
"//submodules/InvisibleInkDustNode:InvisibleInkDustNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import AccountContext
|
|||||||
import AnimationCache
|
import AnimationCache
|
||||||
import MultiAnimationRenderer
|
import MultiAnimationRenderer
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
import InvisibleInkDustNode
|
||||||
|
|
||||||
private extension CGRect {
|
private extension CGRect {
|
||||||
var center: CGPoint {
|
var center: CGPoint {
|
||||||
@@ -287,12 +288,15 @@ public class ImmediateTextNodeWithEntities: TextNode {
|
|||||||
public var textStroke: (UIColor, CGFloat)?
|
public var textStroke: (UIColor, CGFloat)?
|
||||||
public var cutout: TextNodeCutout?
|
public var cutout: TextNodeCutout?
|
||||||
public var displaySpoilers = false
|
public var displaySpoilers = false
|
||||||
|
public var displaySpoilerEffect = true
|
||||||
|
public var spoilerColor: UIColor = .black
|
||||||
|
|
||||||
private var enableLooping: Bool = true
|
private var enableLooping: Bool = true
|
||||||
|
|
||||||
public var arguments: TextNodeWithEntities.Arguments?
|
public var arguments: TextNodeWithEntities.Arguments?
|
||||||
|
|
||||||
private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayer] = [:]
|
private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayer] = [:]
|
||||||
|
private var dustNode: InvisibleInkDustNode?
|
||||||
|
|
||||||
public var visibility: Bool = false {
|
public var visibility: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
@@ -337,7 +341,7 @@ public class ImmediateTextNodeWithEntities: TextNode {
|
|||||||
public var linkHighlightColor: UIColor?
|
public var linkHighlightColor: UIColor?
|
||||||
|
|
||||||
public var trailingLineWidth: CGFloat?
|
public var trailingLineWidth: CGFloat?
|
||||||
|
|
||||||
var constrainedSize: CGSize?
|
var constrainedSize: CGSize?
|
||||||
|
|
||||||
public var highlightAttributeAction: (([NSAttributedString.Key: Any]) -> NSAttributedString.Key?)? {
|
public var highlightAttributeAction: (([NSAttributedString.Key: Any]) -> NSAttributedString.Key?)? {
|
||||||
@@ -378,9 +382,12 @@ public class ImmediateTextNodeWithEntities: TextNode {
|
|||||||
|
|
||||||
let _ = apply()
|
let _ = apply()
|
||||||
|
|
||||||
|
var enableAnimations = true
|
||||||
if let arguments = self.arguments {
|
if let arguments = self.arguments {
|
||||||
self.updateInlineStickers(context: arguments.context, cache: arguments.cache, renderer: arguments.renderer, textLayout: layout, placeholderColor: arguments.placeholderColor)
|
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 {
|
if layout.numberOfLines > 1 {
|
||||||
self.trailingLineWidth = layout.trailingLineWidth
|
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 {
|
public func updateLayoutInfo(_ constrainedSize: CGSize) -> ImmediateTextNodeLayoutInfo {
|
||||||
self.constrainedSize = constrainedSize
|
self.constrainedSize = constrainedSize
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import AccountContext
|
|||||||
import LocalizedPeerData
|
import LocalizedPeerData
|
||||||
import PhotoResources
|
import PhotoResources
|
||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
import InvisibleInkDustNode
|
|
||||||
import TextFormat
|
import TextFormat
|
||||||
import ChatPresentationInterfaceState
|
import ChatPresentationInterfaceState
|
||||||
import TextNodeWithEntities
|
import TextNodeWithEntities
|
||||||
@@ -29,7 +28,6 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
let iconNode: ASImageNode
|
let iconNode: ASImageNode
|
||||||
let titleNode: ImmediateTextNode
|
let titleNode: ImmediateTextNode
|
||||||
let textNode: ImmediateTextNodeWithEntities
|
let textNode: ImmediateTextNodeWithEntities
|
||||||
var dustNode: InvisibleInkDustNode?
|
|
||||||
let imageNode: TransformImageNode
|
let imageNode: TransformImageNode
|
||||||
|
|
||||||
private let actionArea: AccessibilityAreaNode
|
private let actionArea: AccessibilityAreaNode
|
||||||
@@ -73,6 +71,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
self.textNode.displaysAsynchronously = false
|
self.textNode.displaysAsynchronously = false
|
||||||
self.textNode.insets = UIEdgeInsets(top: 3.0, left: 0.0, bottom: 3.0, right: 0.0)
|
self.textNode.insets = UIEdgeInsets(top: 3.0, left: 0.0, bottom: 3.0, right: 0.0)
|
||||||
self.textNode.visibility = true
|
self.textNode.visibility = true
|
||||||
|
self.textNode.spoilerColor = self.theme.chat.inputPanel.secondaryTextColor
|
||||||
|
|
||||||
if let animationCache = animationCache, let animationRenderer = animationRenderer {
|
if let animationCache = animationCache, let animationRenderer = animationRenderer {
|
||||||
self.textNode.arguments = TextNodeWithEntities.Arguments(
|
self.textNode.arguments = TextNodeWithEntities.Arguments(
|
||||||
@@ -293,6 +292,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
if let text = self.textNode.attributedText?.string {
|
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.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 {
|
if let (size, inset, interfaceState) = self.validLayout {
|
||||||
self.updateState(size: size, inset: inset, interfaceState: interfaceState)
|
self.updateState(size: size, inset: inset, interfaceState: interfaceState)
|
||||||
@@ -345,21 +345,6 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
if self.textNode.supernode == self {
|
if self.textNode.supernode == self {
|
||||||
self.textNode.frame = textFrame
|
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() {
|
@objc func closePressed() {
|
||||||
|
|||||||
Reference in New Issue
Block a user