mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Add global search query cache
This commit is contained in:
@@ -1073,6 +1073,14 @@ private func addAttachment(attachment: UIImage, line: InteractiveTextNodeLine, a
|
||||
}
|
||||
|
||||
open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecognizerDelegate {
|
||||
public final class AnimationArguments {
|
||||
public let spoilerExpandRect: CGRect?
|
||||
|
||||
public init(spoilerExpandRect: CGRect?) {
|
||||
self.spoilerExpandRect = spoilerExpandRect
|
||||
}
|
||||
}
|
||||
|
||||
public struct RenderContentTypes: OptionSet {
|
||||
public var rawValue: Int
|
||||
|
||||
@@ -1106,7 +1114,7 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
|
||||
public var canHandleTapAtPoint: ((CGPoint) -> Bool)?
|
||||
public var requestToggleBlockCollapsed: ((Int) -> Void)?
|
||||
public var requestDisplayContentsUnderSpoilers: (() -> Void)?
|
||||
public var requestDisplayContentsUnderSpoilers: ((CGPoint?) -> Void)?
|
||||
private var tapRecognizer: UITapGestureRecognizer?
|
||||
|
||||
public var currentText: NSAttributedString? {
|
||||
@@ -1676,7 +1684,7 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
return calculateLayoutV2(attributedString: attributedString, minimumNumberOfLines: minimumNumberOfLines, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, backgroundColor: backgroundColor, constrainedSize: constrainedSize, alignment: alignment, verticalAlignment: verticalAlignment, lineSpacingFactor: lineSpacingFactor, cutout: cutout, insets: insets, lineColor: lineColor, textShadowColor: textShadowColor, textShadowBlur: textShadowBlur, textStroke: textStroke, displayContentsUnderSpoilers: displayContentsUnderSpoilers, customTruncationToken: customTruncationToken, expandedBlocks: expandedBlocks)
|
||||
}
|
||||
|
||||
private func updateContentItems(animation: ListViewItemUpdateAnimation) {
|
||||
private func updateContentItems(animation: ListViewItemUpdateAnimation, animationArguments: AnimationArguments?) {
|
||||
guard let cachedLayout = self.cachedLayout else {
|
||||
return
|
||||
}
|
||||
@@ -1729,8 +1737,15 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
|
||||
var contentItemAnimation = animation
|
||||
let contentItemLayer: TextContentItemLayer
|
||||
var itemSpoilerExpandRect: CGRect?
|
||||
var itemAnimateContents = animateContents && contentItemAnimation.isAnimated
|
||||
if let current = self.contentItemLayers[itemId] {
|
||||
contentItemLayer = current
|
||||
|
||||
if animation.isAnimated, let spoilerExpandRect = animationArguments?.spoilerExpandRect {
|
||||
itemSpoilerExpandRect = spoilerExpandRect.offsetBy(dx: -contentItemFrame.minX, dy: -contentItemFrame.minY)
|
||||
itemAnimateContents = true
|
||||
}
|
||||
} else {
|
||||
contentItemAnimation = .None
|
||||
contentItemLayer = TextContentItemLayer()
|
||||
@@ -1738,7 +1753,13 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
self.layer.addSublayer(contentItemLayer)
|
||||
}
|
||||
|
||||
contentItemLayer.update(item: contentItem, animation: contentItemAnimation, synchronously: synchronous, animateContents: animateContents && contentItemAnimation.isAnimated)
|
||||
contentItemLayer.update(
|
||||
item: contentItem,
|
||||
animation: contentItemAnimation,
|
||||
synchronously: synchronous,
|
||||
animateContents: itemAnimateContents,
|
||||
spoilerExpandRect: itemSpoilerExpandRect
|
||||
)
|
||||
|
||||
contentItemAnimation.animator.updateFrame(layer: contentItemLayer, frame: contentItemFrame, completion: nil)
|
||||
}
|
||||
@@ -1779,7 +1800,7 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
let point = recognizer.location(in: self.view)
|
||||
if let cachedLayout = self.cachedLayout, !cachedLayout.displayContentsUnderSpoilers, let (_, attributes) = self.attributesAtPoint(point) {
|
||||
if attributes[NSAttributedString.Key(rawValue: "Attribute__Spoiler")] != nil || attributes[NSAttributedString.Key(rawValue: "TelegramSpoiler")] != nil {
|
||||
self.requestDisplayContentsUnderSpoilers?()
|
||||
self.requestDisplayContentsUnderSpoilers?(point)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1789,7 +1810,7 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
}
|
||||
}
|
||||
|
||||
public static func asyncLayout(_ maybeNode: InteractiveTextNode?) -> (InteractiveTextNodeLayoutArguments) -> (InteractiveTextNodeLayout, (ListViewItemUpdateAnimation) -> InteractiveTextNode) {
|
||||
public static func asyncLayout(_ maybeNode: InteractiveTextNode?) -> (InteractiveTextNodeLayoutArguments) -> (InteractiveTextNodeLayout, (ListViewItemUpdateAnimation, AnimationArguments?) -> InteractiveTextNode) {
|
||||
let existingLayout: InteractiveTextNodeLayout? = maybeNode?.cachedLayout
|
||||
|
||||
return { arguments in
|
||||
@@ -1831,10 +1852,10 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
|
||||
let node = maybeNode ?? InteractiveTextNode()
|
||||
|
||||
return (layout, { animation in
|
||||
return (layout, { animation, animationArguments in
|
||||
if node.cachedLayout !== layout {
|
||||
node.cachedLayout = layout
|
||||
node.updateContentItems(animation: animation)
|
||||
node.updateContentItems(animation: animation, animationArguments: animationArguments)
|
||||
}
|
||||
|
||||
return node
|
||||
@@ -2202,7 +2223,13 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(item: TextContentItem, animation: ListViewItemUpdateAnimation, synchronously: Bool = false, animateContents: Bool = false) {
|
||||
func update(
|
||||
item: TextContentItem,
|
||||
animation: ListViewItemUpdateAnimation,
|
||||
synchronously: Bool,
|
||||
animateContents: Bool,
|
||||
spoilerExpandRect: CGRect?
|
||||
) {
|
||||
self.item = item
|
||||
|
||||
let contentFrame = CGRect(origin: CGPoint(), size: item.size)
|
||||
@@ -2241,7 +2268,13 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
return
|
||||
}
|
||||
self.isAnimating = false
|
||||
self.update(item: item, animation: .None, synchronously: true)
|
||||
self.update(
|
||||
item: item,
|
||||
animation: .None,
|
||||
synchronously: true,
|
||||
animateContents: false,
|
||||
spoilerExpandRect: nil
|
||||
)
|
||||
})
|
||||
} else {
|
||||
blockBackgroundView.layer.frame = blockBackgroundFrame
|
||||
@@ -2362,13 +2395,61 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
|
||||
self.renderNode.params = RenderParams(size: contentFrame.size, item: item, mask: staticContentMask)
|
||||
if synchronously {
|
||||
let previousContents = self.renderNode.layer.contents
|
||||
self.renderNode.displayImmediately()
|
||||
if animateContents, let previousContents {
|
||||
animation.transition.animateContents(layer: self.renderNode.layer, from: previousContents)
|
||||
if let spoilerExpandRect {
|
||||
let _ = spoilerExpandRect
|
||||
|
||||
self.renderNode.displayImmediately()
|
||||
|
||||
let maskFrame = self.renderNode.frame
|
||||
|
||||
let maskLayer = SimpleLayer()
|
||||
maskLayer.frame = maskFrame
|
||||
self.addSublayer(maskLayer)
|
||||
|
||||
let maskGradientLayer = SimpleGradientLayer()
|
||||
maskGradientLayer.frame = CGRect(origin: CGPoint(), size: maskFrame.size)
|
||||
setupSpoilerExpansionMaskGradient(
|
||||
gradientLayer: maskGradientLayer,
|
||||
centerLocation: CGPoint(
|
||||
x: 0.5,
|
||||
y: 0.5
|
||||
),
|
||||
radius: CGSize(
|
||||
width: 1.5,
|
||||
height: 1.5
|
||||
),
|
||||
inverse: false
|
||||
)
|
||||
} else {
|
||||
let previousContents = self.renderNode.layer.contents
|
||||
self.renderNode.displayImmediately()
|
||||
if animateContents, let previousContents {
|
||||
animation.transition.animateContents(layer: self.renderNode.layer, from: previousContents)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.renderNode.setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setupSpoilerExpansionMaskGradient(gradientLayer: SimpleGradientLayer, centerLocation: CGPoint, radius: CGSize, inverse: Bool) {
|
||||
let startAlpha: CGFloat = inverse ? 0.0 : 1.0
|
||||
let endAlpha: CGFloat = inverse ? 1.0 : 0.0
|
||||
|
||||
let locations: [CGFloat] = [0.0, 0.7, 0.95, 1.0]
|
||||
let colors: [CGColor] = [
|
||||
UIColor(rgb: 0xff0000, alpha: startAlpha).cgColor,
|
||||
UIColor(rgb: 0xff0000, alpha: startAlpha).cgColor,
|
||||
UIColor(rgb: 0xff0000, alpha: endAlpha).cgColor,
|
||||
UIColor(rgb: 0xff0000, alpha: endAlpha).cgColor
|
||||
]
|
||||
|
||||
gradientLayer.type = .radial
|
||||
gradientLayer.colors = colors
|
||||
gradientLayer.locations = locations.map { $0 as NSNumber }
|
||||
gradientLayer.startPoint = centerLocation
|
||||
|
||||
let endEndPoint = CGPoint(x: (gradientLayer.startPoint.x + radius.width) * 1.0, y: (gradientLayer.startPoint.y + radius.height) * 1.0)
|
||||
gradientLayer.endPoint = endEndPoint
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public final class InteractiveTextNodeWithEntities {
|
||||
public let textColor: UIColor
|
||||
public let spoilerEffectColor: UIColor
|
||||
public let animation: ListViewItemUpdateAnimation
|
||||
public let animationArguments: InteractiveTextNode.AnimationArguments?
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
@@ -74,7 +75,8 @@ public final class InteractiveTextNodeWithEntities {
|
||||
attemptSynchronous: Bool,
|
||||
textColor: UIColor,
|
||||
spoilerEffectColor: UIColor,
|
||||
animation: ListViewItemUpdateAnimation
|
||||
animation: ListViewItemUpdateAnimation,
|
||||
animationArguments: InteractiveTextNode.AnimationArguments?
|
||||
) {
|
||||
self.context = context
|
||||
self.cache = cache
|
||||
@@ -84,6 +86,7 @@ public final class InteractiveTextNodeWithEntities {
|
||||
self.textColor = textColor
|
||||
self.spoilerEffectColor = spoilerEffectColor
|
||||
self.animation = animation
|
||||
self.animationArguments = animationArguments
|
||||
}
|
||||
|
||||
public func withUpdatedPlaceholderColor(_ color: UIColor) -> Arguments {
|
||||
@@ -95,7 +98,8 @@ public final class InteractiveTextNodeWithEntities {
|
||||
attemptSynchronous: self.attemptSynchronous,
|
||||
textColor: self.textColor,
|
||||
spoilerEffectColor: self.spoilerEffectColor,
|
||||
animation: self.animation
|
||||
animation: self.animation,
|
||||
animationArguments: self.animationArguments
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -113,6 +117,7 @@ public final class InteractiveTextNodeWithEntities {
|
||||
|
||||
private var inlineStickerItemLayers: [InlineStickerItemLayer.Key: InlineStickerItemLayerData] = [:]
|
||||
private var dustEffectNodes: [Int: InvisibleInkDustNode] = [:]
|
||||
private var displayContentsUnderSpoilers: Bool?
|
||||
|
||||
private var enableLooping: Bool = true
|
||||
|
||||
@@ -215,11 +220,22 @@ public final class InteractiveTextNodeWithEntities {
|
||||
return (layout, { applyArguments in
|
||||
let animation: ListViewItemUpdateAnimation = applyArguments?.animation ?? .None
|
||||
|
||||
let result = apply(animation)
|
||||
let result = apply(animation, applyArguments?.animationArguments)
|
||||
|
||||
if let maybeNode = maybeNode {
|
||||
if let applyArguments = applyArguments {
|
||||
maybeNode.updateInteractiveContents(context: applyArguments.context, cache: applyArguments.cache, renderer: applyArguments.renderer, textLayout: layout, placeholderColor: applyArguments.placeholderColor, attemptSynchronousLoad: false, textColor: applyArguments.textColor, spoilerEffectColor: applyArguments.spoilerEffectColor, animation: animation)
|
||||
maybeNode.updateInteractiveContents(
|
||||
context: applyArguments.context,
|
||||
cache: applyArguments.cache,
|
||||
renderer: applyArguments.renderer,
|
||||
textLayout: layout,
|
||||
placeholderColor: applyArguments.placeholderColor,
|
||||
attemptSynchronousLoad: false,
|
||||
textColor: applyArguments.textColor,
|
||||
spoilerEffectColor: applyArguments.spoilerEffectColor,
|
||||
animation: animation,
|
||||
animationArguments: applyArguments.animationArguments
|
||||
)
|
||||
}
|
||||
|
||||
return maybeNode
|
||||
@@ -227,7 +243,18 @@ public final class InteractiveTextNodeWithEntities {
|
||||
let resultNode = InteractiveTextNodeWithEntities(textNode: result)
|
||||
|
||||
if let applyArguments = applyArguments {
|
||||
resultNode.updateInteractiveContents(context: applyArguments.context, cache: applyArguments.cache, renderer: applyArguments.renderer, textLayout: layout, placeholderColor: applyArguments.placeholderColor, attemptSynchronousLoad: false, textColor: applyArguments.textColor, spoilerEffectColor: applyArguments.spoilerEffectColor, animation: .None)
|
||||
resultNode.updateInteractiveContents(
|
||||
context: applyArguments.context,
|
||||
cache: applyArguments.cache,
|
||||
renderer: applyArguments.renderer,
|
||||
textLayout: layout,
|
||||
placeholderColor: applyArguments.placeholderColor,
|
||||
attemptSynchronousLoad: false,
|
||||
textColor: applyArguments.textColor,
|
||||
spoilerEffectColor: applyArguments.spoilerEffectColor,
|
||||
animation: .None,
|
||||
animationArguments: nil
|
||||
)
|
||||
}
|
||||
|
||||
return resultNode
|
||||
@@ -253,7 +280,8 @@ public final class InteractiveTextNodeWithEntities {
|
||||
attemptSynchronousLoad: Bool,
|
||||
textColor: UIColor,
|
||||
spoilerEffectColor: UIColor,
|
||||
animation: ListViewItemUpdateAnimation
|
||||
animation: ListViewItemUpdateAnimation,
|
||||
animationArguments: InteractiveTextNode.AnimationArguments?
|
||||
) {
|
||||
self.enableLooping = context.sharedContext.energyUsageSettings.loopEmoji
|
||||
|
||||
@@ -261,6 +289,8 @@ public final class InteractiveTextNodeWithEntities {
|
||||
if let textLayout {
|
||||
displayContentsUnderSpoilers = textLayout.displayContentsUnderSpoilers
|
||||
}
|
||||
let previousDisplayContentsUnderSpoilers = self.displayContentsUnderSpoilers
|
||||
self.displayContentsUnderSpoilers = displayContentsUnderSpoilers
|
||||
|
||||
var nextIndexById: [Int64: Int] = [:]
|
||||
var validIds: [InlineStickerItemLayer.Key] = []
|
||||
@@ -345,7 +375,12 @@ public final class InteractiveTextNodeWithEntities {
|
||||
wordRects: segment.spoilerWords.map { $0.1.offsetBy(dx: segmentItem.contentOffset.x + 3.0, dy: segmentItem.contentOffset.y + 3.0).insetBy(dx: 1.0, dy: 1.0) }
|
||||
)
|
||||
|
||||
animation.transition.updateAlpha(node: dustEffectNode, alpha: displayContentsUnderSpoilers ? 0.0 : 1.0)
|
||||
if let previousDisplayContentsUnderSpoilers, previousDisplayContentsUnderSpoilers != displayContentsUnderSpoilers, displayContentsUnderSpoilers, let currentSpoilerExpandRect = animationArguments?.spoilerExpandRect {
|
||||
let spoilerLocalPosition = self.textNode.layer.convert(currentSpoilerExpandRect.center, to: dustEffectNode.layer)
|
||||
dustEffectNode.revealAtLocation(spoilerLocalPosition)
|
||||
} else {
|
||||
dustEffectNode.update(revealed: displayContentsUnderSpoilers, animated: previousDisplayContentsUnderSpoilers != nil && animation.isAnimated)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user