mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Use static spoiler when energy saving
This commit is contained in:
parent
6fa3948d22
commit
9fddaf9f96
@ -1038,7 +1038,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
|
|||||||
if let current = self.dustNode {
|
if let current = self.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
dustNode.alpha = self.spoilersRevealed ? 0.0 : 1.0
|
dustNode.alpha = self.spoilersRevealed ? 0.0 : 1.0
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
textInputNode.textView.addSubview(dustNode.view)
|
textInputNode.textView.addSubview(dustNode.view)
|
||||||
@ -1298,7 +1298,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
|
|||||||
private func updateOneLineSpoiler() {
|
private func updateOneLineSpoiler() {
|
||||||
if let textLayout = self.oneLineNode.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
if let textLayout = self.oneLineNode.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
||||||
if self.oneLineDustNode == nil {
|
if self.oneLineDustNode == nil {
|
||||||
let oneLineDustNode = InvisibleInkDustNode(textNode: nil)
|
let oneLineDustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
self.oneLineDustNode = oneLineDustNode
|
self.oneLineDustNode = oneLineDustNode
|
||||||
self.oneLineNode.textNode.supernode?.insertSubnode(oneLineDustNode, aboveSubnode: self.oneLineNode.textNode)
|
self.oneLineNode.textNode.supernode?.insertSubnode(oneLineDustNode, aboveSubnode: self.oneLineNode.textNode)
|
||||||
|
|
||||||
|
|||||||
@ -549,7 +549,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
|
|
||||||
if let textLayout = self.currentOptionNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
if let textLayout = self.currentOptionNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
||||||
if self.dustNode == nil {
|
if self.dustNode == nil {
|
||||||
let dustNode = InvisibleInkDustNode(textNode: nil)
|
let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: true)
|
||||||
self.dustNode = dustNode
|
self.dustNode = dustNode
|
||||||
self.currentOptionNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.currentOptionNode)
|
self.currentOptionNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.currentOptionNode)
|
||||||
|
|
||||||
|
|||||||
@ -3124,7 +3124,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
if let current = strongSelf.dustNode {
|
if let current = strongSelf.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
strongSelf.dustNode = dustNode
|
strongSelf.dustNode = dustNode
|
||||||
|
|
||||||
|
|||||||
@ -813,7 +813,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
|||||||
self.spoilerTextNode = spoilerTextNode
|
self.spoilerTextNode = spoilerTextNode
|
||||||
self.textNode.supernode?.insertSubnode(spoilerTextNode, aboveSubnode: self.textNode)
|
self.textNode.supernode?.insertSubnode(spoilerTextNode, aboveSubnode: self.textNode)
|
||||||
|
|
||||||
let dustNode = InvisibleInkDustNode(textNode: spoilerTextNode)
|
let dustNode = InvisibleInkDustNode(textNode: spoilerTextNode, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
self.dustNode = dustNode
|
self.dustNode = dustNode
|
||||||
spoilerTextNode.supernode?.insertSubnode(dustNode, aboveSubnode: spoilerTextNode)
|
spoilerTextNode.supernode?.insertSubnode(dustNode, aboveSubnode: spoilerTextNode)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,25 @@ import AsyncDisplayKit
|
|||||||
import Display
|
import Display
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
|
import GameplayKit
|
||||||
|
|
||||||
|
private struct ArbitraryRandomNumberGenerator : RandomNumberGenerator {
|
||||||
|
init(seed: Int) { srand48(seed) }
|
||||||
|
func next() -> UInt64 { return UInt64(drand48() * Double(UInt64.max)) }
|
||||||
|
}
|
||||||
|
// mutating func next() -> UInt64 {
|
||||||
|
// // GKRandom produces values in [INT32_MIN, INT32_MAX] range; hence we need two numbers to produce 64-bit value.
|
||||||
|
// let next1 = UInt64(bitPattern: Int64(gkrandom.nextInt()))
|
||||||
|
// let next2 = UInt64(bitPattern: Int64(gkrandom.nextInt()))
|
||||||
|
// return next1 ^ (next2 << 32)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// init(seed: UInt64) {
|
||||||
|
// self.gkrandom = GKMersenneTwisterRandomSource(seed: seed)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private let gkrandom: GKRandom
|
||||||
|
//}
|
||||||
|
|
||||||
func createEmitterBehavior(type: String) -> NSObject {
|
func createEmitterBehavior(type: String) -> NSObject {
|
||||||
let selector = ["behaviorWith", "Type:"].joined(separator: "")
|
let selector = ["behaviorWith", "Type:"].joined(separator: "")
|
||||||
@ -45,6 +64,7 @@ func generateMaskImage(size originalSize: CGSize, position: CGPoint, inverse: Bo
|
|||||||
public class InvisibleInkDustNode: ASDisplayNode {
|
public class InvisibleInkDustNode: ASDisplayNode {
|
||||||
private var currentParams: (size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect])?
|
private var currentParams: (size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect])?
|
||||||
private var animColor: CGColor?
|
private var animColor: CGColor?
|
||||||
|
private let enableAnimations: Bool
|
||||||
|
|
||||||
private weak var textNode: TextNode?
|
private weak var textNode: TextNode?
|
||||||
private let textMaskNode: ASDisplayNode
|
private let textMaskNode: ASDisplayNode
|
||||||
@ -57,11 +77,15 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
private let emitterSpotNode: ASImageNode
|
private let emitterSpotNode: ASImageNode
|
||||||
private let emitterMaskFillNode: ASDisplayNode
|
private let emitterMaskFillNode: ASDisplayNode
|
||||||
|
|
||||||
|
private var staticNode: ASImageNode?
|
||||||
|
private var staticParams: (size: CGSize, color: UIColor, rects: [CGRect])?
|
||||||
|
|
||||||
public var isRevealed = false
|
public var isRevealed = false
|
||||||
private var isExploding = false
|
private var isExploding = false
|
||||||
|
|
||||||
public init(textNode: TextNode?) {
|
public init(textNode: TextNode?, enableAnimations: Bool) {
|
||||||
self.textNode = textNode
|
self.textNode = textNode
|
||||||
|
self.enableAnimations = enableAnimations
|
||||||
|
|
||||||
self.emitterNode = ASDisplayNode()
|
self.emitterNode = ASDisplayNode()
|
||||||
self.emitterNode.isUserInteractionEnabled = false
|
self.emitterNode.isUserInteractionEnabled = false
|
||||||
@ -94,6 +118,7 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
public override func didLoad() {
|
public override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
|
if self.enableAnimations {
|
||||||
let emitter = CAEmitterCell()
|
let emitter = CAEmitterCell()
|
||||||
emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage
|
emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage
|
||||||
emitter.contentsScale = 1.8
|
emitter.contentsScale = 1.8
|
||||||
@ -135,6 +160,11 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
self.emitterLayer = emitterLayer
|
self.emitterLayer = emitterLayer
|
||||||
|
|
||||||
self.emitterNode.layer.addSublayer(emitterLayer)
|
self.emitterNode.layer.addSublayer(emitterLayer)
|
||||||
|
} else {
|
||||||
|
let staticNode = ASImageNode()
|
||||||
|
self.staticNode = staticNode
|
||||||
|
self.addSubnode(staticNode)
|
||||||
|
}
|
||||||
|
|
||||||
self.updateEmitter()
|
self.updateEmitter()
|
||||||
|
|
||||||
@ -170,6 +200,8 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.isRevealed = true
|
self.isRevealed = true
|
||||||
|
|
||||||
|
if self.enableAnimations {
|
||||||
self.isExploding = true
|
self.isExploding = true
|
||||||
|
|
||||||
let position = gestureRecognizer.location(in: self.view)
|
let position = gestureRecognizer.location(in: self.view)
|
||||||
@ -233,13 +265,21 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
self.emitterSpotNode.layer.removeAllAnimations()
|
self.emitterSpotNode.layer.removeAllAnimations()
|
||||||
self.emitterMaskFillNode.layer.removeAllAnimations()
|
self.emitterMaskFillNode.layer.removeAllAnimations()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
textNode.alpha = 1.0
|
||||||
|
textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||||
|
|
||||||
|
self.staticNode?.alpha = 0.0
|
||||||
|
self.staticNode?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateEmitter() {
|
private func updateEmitter() {
|
||||||
guard let (size, color, _, _, wordRects) = self.currentParams else {
|
guard let (size, color, _, lineRects, wordRects) = self.currentParams else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.enableAnimations {
|
||||||
self.emitter?.color = self.animColor ?? color.cgColor
|
self.emitter?.color = self.animColor ?? color.cgColor
|
||||||
self.emitterLayer?.setValue(wordRects, forKey: "emitterRects")
|
self.emitterLayer?.setValue(wordRects, forKey: "emitterRects")
|
||||||
self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size)
|
self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
@ -256,16 +296,68 @@ public class InvisibleInkDustNode: ASDisplayNode {
|
|||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
self.emitter?.birthRate = min(100000, square * 0.35)
|
self.emitter?.birthRate = min(100000, square * 0.35)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if let staticParams = self.staticParams, staticParams.size == size && staticParams.color == color && staticParams.rects == lineRects && self.staticNode?.image != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.staticParams = (size, color, lineRects)
|
||||||
|
|
||||||
|
let start = CACurrentMediaTime()
|
||||||
|
|
||||||
|
var combinedRect: CGRect?
|
||||||
|
var combinedRects: [CGRect] = []
|
||||||
|
for rect in lineRects {
|
||||||
|
if let currentRect = combinedRect {
|
||||||
|
if abs(currentRect.minY - rect.minY) < 1.0 && abs(currentRect.maxY - rect.maxY) < 1.0 {
|
||||||
|
combinedRect = currentRect.union(rect)
|
||||||
|
} else {
|
||||||
|
combinedRects.append(currentRect.insetBy(dx: 0.0, dy: -1.0 + UIScreenPixel))
|
||||||
|
combinedRect = rect
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
combinedRect = rect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let combinedRect {
|
||||||
|
combinedRects.append(combinedRect.insetBy(dx: 0.0, dy: -1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
print("combining \(CACurrentMediaTime() - start)")
|
||||||
|
|
||||||
|
var generator = ArbitraryRandomNumberGenerator(seed: 1)
|
||||||
|
let image = generateImage(size, rotatedContext: { size, context in
|
||||||
|
let bounds = CGRect(origin: .zero, size: size)
|
||||||
|
context.clear(bounds)
|
||||||
|
|
||||||
|
context.setFillColor(color.cgColor)
|
||||||
|
for rect in combinedRects {
|
||||||
|
if rect.width > 10.0 {
|
||||||
|
let rate = Int(rect.width * rect.height * 0.25)
|
||||||
|
for _ in 0 ..< rate {
|
||||||
|
let location = CGPoint(x: .random(in: rect.minX ..< rect.maxX, using: &generator), y: .random(in: rect.minY ..< rect.maxY, using: &generator))
|
||||||
|
context.fillEllipse(in: CGRect(origin: location, size: CGSize(width: 1.0, height: 1.0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.staticNode?.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
self.staticNode?.image = image
|
||||||
|
|
||||||
|
print("total draw \(CACurrentMediaTime() - start)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func update(size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect]) {
|
public func update(size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect]) {
|
||||||
self.currentParams = (size, color, textColor, rects, wordRects)
|
self.currentParams = (size, color, textColor, rects, wordRects)
|
||||||
|
|
||||||
self.emitterNode.frame = CGRect(origin: CGPoint(), size: size)
|
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||||
self.emitterMaskNode.frame = self.emitterNode.bounds
|
self.emitterNode.frame = bounds
|
||||||
self.emitterMaskFillNode.frame = self.emitterNode.bounds
|
self.emitterMaskNode.frame = bounds
|
||||||
|
self.emitterMaskFillNode.frame = bounds
|
||||||
self.textMaskNode.frame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: size)
|
self.textMaskNode.frame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: size)
|
||||||
|
|
||||||
|
self.staticNode?.frame = bounds
|
||||||
|
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
self.updateEmitter()
|
self.updateEmitter()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -249,12 +249,6 @@ public func cacheAnimatedStickerFrames(data: Data, size: CGSize, fitzModifier: E
|
|||||||
|
|
||||||
subscriber.putNext(.tempFile(tempFile))
|
subscriber.putNext(.tempFile(tempFile))
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
/*print("animation render time \(CACurrentMediaTime() - startTime)")
|
|
||||||
print("of which drawing time \(drawingTime)")
|
|
||||||
print("of which appending time \(appendingTime)")
|
|
||||||
print("of which delta time \(deltaTime)")
|
|
||||||
|
|
||||||
print("of which compression time \(compressionTime)")*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -399,12 +393,6 @@ public func cacheVideoStickerFrames(path: String, size: CGSize, cacheKey: String
|
|||||||
|
|
||||||
subscriber.putNext(.tempFile(tempFile))
|
subscriber.putNext(.tempFile(tempFile))
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
/*print("animation render time \(CACurrentMediaTime() - startTime)")
|
|
||||||
print("of which drawing time \(drawingTime)")
|
|
||||||
print("of which appending time \(appendingTime)")
|
|
||||||
print("of which delta time \(deltaTime)")
|
|
||||||
|
|
||||||
print("of which compression time \(compressionTime)")*/
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return ActionDisposable {
|
return ActionDisposable {
|
||||||
|
|||||||
@ -316,7 +316,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
if let current = strongSelf.dustNode {
|
if let current = strongSelf.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
strongSelf.dustNode = dustNode
|
strongSelf.dustNode = dustNode
|
||||||
strongSelf.insertSubnode(dustNode, aboveSubnode: strongSelf.labelNode.textNode)
|
strongSelf.insertSubnode(dustNode, aboveSubnode: strongSelf.labelNode.textNode)
|
||||||
|
|||||||
@ -436,12 +436,13 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
|
|||||||
|
|
||||||
transition.updateFrame(node: self.imageNode, frame: CGRect(origin: CGPoint(x: width - 10.0 - imageSize.width, y: (panelHeight - imageSize.height) / 2.0), size: imageSize))
|
transition.updateFrame(node: self.imageNode, frame: CGRect(origin: CGPoint(x: width - 10.0 - imageSize.width, y: (panelHeight - imageSize.height) / 2.0), size: imageSize))
|
||||||
|
|
||||||
if !textLayout.spoilers.isEmpty, let presentationData = self.item?.context.sharedContext.currentPresentationData.with({ $0 }) {
|
if !textLayout.spoilers.isEmpty, let item = self.item {
|
||||||
|
let presentationData = item.context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
let dustNode: InvisibleInkDustNode
|
let dustNode: InvisibleInkDustNode
|
||||||
if let current = self.dustNode {
|
if let current = self.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
self.dustNode = dustNode
|
self.dustNode = dustNode
|
||||||
self.insertSubnode(dustNode, aboveSubnode: self.textNode.textNode)
|
self.insertSubnode(dustNode, aboveSubnode: self.textNode.textNode)
|
||||||
|
|||||||
@ -344,7 +344,7 @@ class ChatMessageReplyInfoNode: ASDisplayNode {
|
|||||||
if let current = node.dustNode {
|
if let current = node.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: arguments.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
node.dustNode = dustNode
|
node.dustNode = dustNode
|
||||||
node.contentNode.insertSubnode(dustNode, aboveSubnode: textNode.textNode)
|
node.contentNode.insertSubnode(dustNode, aboveSubnode: textNode.textNode)
|
||||||
|
|||||||
@ -485,7 +485,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
if let current = strongSelf.dustNode {
|
if let current = strongSelf.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode)
|
dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
strongSelf.dustNode = dustNode
|
strongSelf.dustNode = dustNode
|
||||||
strongSelf.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode)
|
strongSelf.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -764,7 +764,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||||||
if let current = strongSelf.dustNode {
|
if let current = strongSelf.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode)
|
dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode, enableAnimations: strongSelf.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
strongSelf.dustNode = dustNode
|
strongSelf.dustNode = dustNode
|
||||||
strongSelf.contentTextContainer.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode)
|
strongSelf.contentTextContainer.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2289,10 +2289,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
if let start = textInputNode.textView.position(from: beginning, offset: startIndex), let end = textInputNode.textView.position(from: start, offset: endIndex - startIndex), let textRange = textInputNode.textView.textRange(from: start, to: end) {
|
if let start = textInputNode.textView.position(from: beginning, offset: startIndex), let end = textInputNode.textView.position(from: start, offset: endIndex - startIndex), let textRange = textInputNode.textView.textRange(from: start, to: end) {
|
||||||
let textRects = textInputNode.textView.selectionRects(for: textRange)
|
let textRects = textInputNode.textView.selectionRects(for: textRange)
|
||||||
for textRect in textRects {
|
for textRect in textRects {
|
||||||
|
if textRect.rect.width > 1.0 && textRect.rect.size.height > 1.0 {
|
||||||
rects.append(textRect.rect.insetBy(dx: 1.0, dy: 1.0).offsetBy(dx: 0.0, dy: 1.0))
|
rects.append(textRect.rect.insetBy(dx: 1.0, dy: 1.0).offsetBy(dx: 0.0, dy: 1.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var startIndex: Int?
|
var startIndex: Int?
|
||||||
var currentIndex: Int?
|
var currentIndex: Int?
|
||||||
@ -2335,7 +2337,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
|||||||
if let current = self.dustNode {
|
if let current = self.dustNode {
|
||||||
dustNode = current
|
dustNode = current
|
||||||
} else {
|
} else {
|
||||||
dustNode = InvisibleInkDustNode(textNode: nil)
|
dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context?.sharedContext.energyUsageSettings.fullTranslucency ?? true)
|
||||||
dustNode.alpha = self.spoilersRevealed ? 0.0 : 1.0
|
dustNode.alpha = self.spoilersRevealed ? 0.0 : 1.0
|
||||||
dustNode.isUserInteractionEnabled = false
|
dustNode.isUserInteractionEnabled = false
|
||||||
textInputNode.textView.addSubview(dustNode.view)
|
textInputNode.textView.addSubview(dustNode.view)
|
||||||
|
|||||||
@ -34,6 +34,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
|
|
||||||
private let actionArea: AccessibilityAreaNode
|
private let actionArea: AccessibilityAreaNode
|
||||||
|
|
||||||
|
private let context: AccountContext
|
||||||
var theme: PresentationTheme
|
var theme: PresentationTheme
|
||||||
var strings: PresentationStrings
|
var strings: PresentationStrings
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
init(context: AccountContext, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, animationCache: AnimationCache?, animationRenderer: MultiAnimationRenderer?) {
|
init(context: AccountContext, messageId: MessageId, theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, dateTimeFormat: PresentationDateTimeFormat, animationCache: AnimationCache?, animationRenderer: MultiAnimationRenderer?) {
|
||||||
self.messageId = messageId
|
self.messageId = messageId
|
||||||
|
|
||||||
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
|
|
||||||
@ -344,7 +346,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode {
|
|||||||
|
|
||||||
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty {
|
||||||
if self.dustNode == nil {
|
if self.dustNode == nil {
|
||||||
let dustNode = InvisibleInkDustNode(textNode: nil)
|
let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency)
|
||||||
self.dustNode = dustNode
|
self.dustNode = dustNode
|
||||||
self.textNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.textNode)
|
self.textNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.textNode)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user