From 9fddaf9f9687cb45a3b342612eee8425ab874f33 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 3 Mar 2023 16:48:20 +0400 Subject: [PATCH] Use static spoiler when energy saving --- .../AttachmentTextInputPanelNode.swift | 4 +- ...ationSequenceCodeEntryControllerNode.swift | 2 +- .../Sources/Node/ChatListItem.swift | 2 +- .../ChatItemGalleryFooterContentNode.swift | 2 +- .../Sources/InvisibleInkDustNode.swift | 328 +++++++++++------- .../Sources/AnimatedStickerUtils.swift | 12 - .../Sources/ChatMessageActionItemNode.swift | 2 +- .../Sources/ChatMessageNotificationItem.swift | 5 +- .../Sources/ChatMessageReplyInfoNode.swift | 2 +- .../ChatMessageTextBubbleContentNode.swift | 2 +- .../ChatPinnedMessageTitlePanelNode.swift | 2 +- .../Sources/ChatTextInputPanelNode.swift | 6 +- .../Sources/ReplyAccessoryPanelNode.swift | 4 +- 13 files changed, 229 insertions(+), 144 deletions(-) diff --git a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift index be35d4fdfb..77ccdbda2e 100644 --- a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift +++ b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift @@ -1038,7 +1038,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS if let current = self.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: nil) + dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency) dustNode.alpha = self.spoilersRevealed ? 0.0 : 1.0 dustNode.isUserInteractionEnabled = false textInputNode.textView.addSubview(dustNode.view) @@ -1298,7 +1298,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS private func updateOneLineSpoiler() { if let textLayout = self.oneLineNode.textNode.cachedLayout, !textLayout.spoilers.isEmpty { if self.oneLineDustNode == nil { - let oneLineDustNode = InvisibleInkDustNode(textNode: nil) + let oneLineDustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency) self.oneLineDustNode = oneLineDustNode self.oneLineNode.textNode.supernode?.insertSubnode(oneLineDustNode, aboveSubnode: self.oneLineNode.textNode) diff --git a/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift b/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift index bff27a5960..3c4d45d3fb 100644 --- a/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift +++ b/submodules/AuthorizationUI/Sources/AuthorizationSequenceCodeEntryControllerNode.swift @@ -549,7 +549,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF if let textLayout = self.currentOptionNode.cachedLayout, !textLayout.spoilers.isEmpty { if self.dustNode == nil { - let dustNode = InvisibleInkDustNode(textNode: nil) + let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: true) self.dustNode = dustNode self.currentOptionNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.currentOptionNode) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index d68e04cf0d..d8f8edc90d 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -3124,7 +3124,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { if let current = strongSelf.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: nil) + dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency) dustNode.isUserInteractionEnabled = false strongSelf.dustNode = dustNode diff --git a/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift b/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift index 7f11759202..df0a45bf49 100644 --- a/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift +++ b/submodules/GalleryUI/Sources/ChatItemGalleryFooterContentNode.swift @@ -813,7 +813,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll self.spoilerTextNode = spoilerTextNode 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 spoilerTextNode.supernode?.insertSubnode(dustNode, aboveSubnode: spoilerTextNode) diff --git a/submodules/InvisibleInkDustNode/Sources/InvisibleInkDustNode.swift b/submodules/InvisibleInkDustNode/Sources/InvisibleInkDustNode.swift index 661a90ca71..b8ba77c842 100644 --- a/submodules/InvisibleInkDustNode/Sources/InvisibleInkDustNode.swift +++ b/submodules/InvisibleInkDustNode/Sources/InvisibleInkDustNode.swift @@ -6,6 +6,25 @@ import AsyncDisplayKit import Display import AppBundle 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 { let selector = ["behaviorWith", "Type:"].joined(separator: "") @@ -45,6 +64,7 @@ func generateMaskImage(size originalSize: CGSize, position: CGPoint, inverse: Bo public class InvisibleInkDustNode: ASDisplayNode { private var currentParams: (size: CGSize, color: UIColor, textColor: UIColor, rects: [CGRect], wordRects: [CGRect])? private var animColor: CGColor? + private let enableAnimations: Bool private weak var textNode: TextNode? private let textMaskNode: ASDisplayNode @@ -56,12 +76,16 @@ public class InvisibleInkDustNode: ASDisplayNode { private let emitterMaskNode: ASDisplayNode private let emitterSpotNode: ASImageNode private let emitterMaskFillNode: ASDisplayNode + + private var staticNode: ASImageNode? + private var staticParams: (size: CGSize, color: UIColor, rects: [CGRect])? public var isRevealed = false private var isExploding = false - public init(textNode: TextNode?) { + public init(textNode: TextNode?, enableAnimations: Bool) { self.textNode = textNode + self.enableAnimations = enableAnimations self.emitterNode = ASDisplayNode() self.emitterNode.isUserInteractionEnabled = false @@ -94,47 +118,53 @@ public class InvisibleInkDustNode: ASDisplayNode { public override func didLoad() { super.didLoad() - let emitter = CAEmitterCell() - emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage - emitter.contentsScale = 1.8 - emitter.emissionRange = .pi * 2.0 - emitter.lifetime = 1.0 - emitter.scale = 0.5 - emitter.velocityRange = 20.0 - emitter.name = "dustCell" - emitter.alphaRange = 1.0 - emitter.setValue("point", forKey: "particleType") - emitter.setValue(3.0, forKey: "mass") - emitter.setValue(2.0, forKey: "massRange") - self.emitter = emitter - - let fingerAttractor = createEmitterBehavior(type: "simpleAttractor") - fingerAttractor.setValue("fingerAttractor", forKey: "name") - - let alphaBehavior = createEmitterBehavior(type: "valueOverLife") - alphaBehavior.setValue("color.alpha", forKey: "keyPath") - alphaBehavior.setValue([0.0, 0.0, 1.0, 0.0, -1.0], forKey: "values") - alphaBehavior.setValue(true, forKey: "additive") - - let behaviors = [fingerAttractor, alphaBehavior] - - let emitterLayer = CAEmitterLayer() - emitterLayer.masksToBounds = true - emitterLayer.allowsGroupOpacity = true - emitterLayer.lifetime = 1 - emitterLayer.emitterCells = [emitter] - emitterLayer.emitterPosition = CGPoint(x: 0, y: 0) - emitterLayer.seed = arc4random() - emitterLayer.emitterSize = CGSize(width: 1, height: 1) - emitterLayer.emitterShape = CAEmitterLayerEmitterShape(rawValue: "rectangles") - emitterLayer.setValue(behaviors, forKey: "emitterBehaviors") - - emitterLayer.setValue(4.0, forKeyPath: "emitterBehaviors.fingerAttractor.stiffness") - emitterLayer.setValue(false, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") - - self.emitterLayer = emitterLayer - - self.emitterNode.layer.addSublayer(emitterLayer) + if self.enableAnimations { + let emitter = CAEmitterCell() + emitter.contents = UIImage(bundleImageName: "Components/TextSpeckle")?.cgImage + emitter.contentsScale = 1.8 + emitter.emissionRange = .pi * 2.0 + emitter.lifetime = 1.0 + emitter.scale = 0.5 + emitter.velocityRange = 20.0 + emitter.name = "dustCell" + emitter.alphaRange = 1.0 + emitter.setValue("point", forKey: "particleType") + emitter.setValue(3.0, forKey: "mass") + emitter.setValue(2.0, forKey: "massRange") + self.emitter = emitter + + let fingerAttractor = createEmitterBehavior(type: "simpleAttractor") + fingerAttractor.setValue("fingerAttractor", forKey: "name") + + let alphaBehavior = createEmitterBehavior(type: "valueOverLife") + alphaBehavior.setValue("color.alpha", forKey: "keyPath") + alphaBehavior.setValue([0.0, 0.0, 1.0, 0.0, -1.0], forKey: "values") + alphaBehavior.setValue(true, forKey: "additive") + + let behaviors = [fingerAttractor, alphaBehavior] + + let emitterLayer = CAEmitterLayer() + emitterLayer.masksToBounds = true + emitterLayer.allowsGroupOpacity = true + emitterLayer.lifetime = 1 + emitterLayer.emitterCells = [emitter] + emitterLayer.emitterPosition = CGPoint(x: 0, y: 0) + emitterLayer.seed = arc4random() + emitterLayer.emitterSize = CGSize(width: 1, height: 1) + emitterLayer.emitterShape = CAEmitterLayerEmitterShape(rawValue: "rectangles") + emitterLayer.setValue(behaviors, forKey: "emitterBehaviors") + + emitterLayer.setValue(4.0, forKeyPath: "emitterBehaviors.fingerAttractor.stiffness") + emitterLayer.setValue(false, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") + + self.emitterLayer = emitterLayer + + self.emitterNode.layer.addSublayer(emitterLayer) + } else { + let staticNode = ASImageNode() + self.staticNode = staticNode + self.addSubnode(staticNode) + } self.updateEmitter() @@ -170,102 +200,164 @@ public class InvisibleInkDustNode: ASDisplayNode { } self.isRevealed = true - self.isExploding = true - let position = gestureRecognizer.location(in: self.view) - self.emitterLayer?.setValue(true, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") - self.emitterLayer?.setValue(position, forKeyPath: "emitterBehaviors.fingerAttractor.position") - - let maskSize = self.emitterNode.frame.size - Queue.concurrentDefaultQueue().async { - let textMaskImage = generateMaskImage(size: maskSize, position: position, inverse: false) - let emitterMaskImage = generateMaskImage(size: maskSize, position: position, inverse: true) + if self.enableAnimations { + self.isExploding = true - Queue.mainQueue().async { - self.textSpotNode.image = textMaskImage - self.emitterSpotNode.image = emitterMaskImage + let position = gestureRecognizer.location(in: self.view) + self.emitterLayer?.setValue(true, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") + self.emitterLayer?.setValue(position, forKeyPath: "emitterBehaviors.fingerAttractor.position") + + let maskSize = self.emitterNode.frame.size + Queue.concurrentDefaultQueue().async { + let textMaskImage = generateMaskImage(size: maskSize, position: position, inverse: false) + let emitterMaskImage = generateMaskImage(size: maskSize, position: position, inverse: true) + + Queue.mainQueue().async { + self.textSpotNode.image = textMaskImage + self.emitterSpotNode.image = emitterMaskImage + } } - } - - Queue.mainQueue().after(0.1 * UIView.animationDurationFactor()) { + + Queue.mainQueue().after(0.1 * UIView.animationDurationFactor()) { + textNode.alpha = 1.0 + + textNode.view.mask = self.textMaskNode.view + self.textSpotNode.frame = CGRect(x: 0.0, y: 0.0, width: self.emitterMaskNode.frame.width * 3.0, height: self.emitterMaskNode.frame.height * 3.0) + + let xFactor = (position.x / self.emitterNode.frame.width - 0.5) * 2.0 + let yFactor = (position.y / self.emitterNode.frame.height - 0.5) * 2.0 + let maxFactor = max(abs(xFactor), abs(yFactor)) + + var scaleAddition = maxFactor * 4.0 + var durationAddition = -maxFactor * 0.2 + if self.emitterNode.frame.height > 0.0, self.emitterNode.frame.width / self.emitterNode.frame.height < 0.7 { + scaleAddition *= 5.0 + durationAddition *= 2.0 + } + + self.textSpotNode.layer.anchorPoint = CGPoint(x: position.x / self.emitterMaskNode.frame.width, y: position.y / self.emitterMaskNode.frame.height) + self.textSpotNode.position = position + self.textSpotNode.layer.animateScale(from: 0.3333, to: 10.5 + scaleAddition, duration: 0.55 + durationAddition, removeOnCompletion: false, completion: { _ in + textNode.view.mask = nil + }) + self.textSpotNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) + + self.emitterNode.view.mask = self.emitterMaskNode.view + self.emitterSpotNode.frame = CGRect(x: 0.0, y: 0.0, width: self.emitterMaskNode.frame.width * 3.0, height: self.emitterMaskNode.frame.height * 3.0) + + self.emitterSpotNode.layer.anchorPoint = CGPoint(x: position.x / self.emitterMaskNode.frame.width, y: position.y / self.emitterMaskNode.frame.height) + self.emitterSpotNode.position = position + self.emitterSpotNode.layer.animateScale(from: 0.3333, to: 10.5 + scaleAddition, duration: 0.55 + durationAddition, removeOnCompletion: false, completion: { [weak self] _ in + self?.alpha = 0.0 + self?.emitterNode.view.mask = nil + + self?.emitter?.color = textColor.cgColor + }) + self.emitterMaskFillNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) + } + + Queue.mainQueue().after(0.8 * UIView.animationDurationFactor()) { + self.isExploding = false + self.emitterLayer?.setValue(false, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") + self.textSpotNode.layer.removeAllAnimations() + + self.emitterSpotNode.layer.removeAllAnimations() + self.emitterMaskFillNode.layer.removeAllAnimations() + } + } else { textNode.alpha = 1.0 + textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25) - textNode.view.mask = self.textMaskNode.view - self.textSpotNode.frame = CGRect(x: 0.0, y: 0.0, width: self.emitterMaskNode.frame.width * 3.0, height: self.emitterMaskNode.frame.height * 3.0) - - let xFactor = (position.x / self.emitterNode.frame.width - 0.5) * 2.0 - let yFactor = (position.y / self.emitterNode.frame.height - 0.5) * 2.0 - let maxFactor = max(abs(xFactor), abs(yFactor)) - - var scaleAddition = maxFactor * 4.0 - var durationAddition = -maxFactor * 0.2 - if self.emitterNode.frame.height > 0.0, self.emitterNode.frame.width / self.emitterNode.frame.height < 0.7 { - scaleAddition *= 5.0 - durationAddition *= 2.0 - } - - self.textSpotNode.layer.anchorPoint = CGPoint(x: position.x / self.emitterMaskNode.frame.width, y: position.y / self.emitterMaskNode.frame.height) - self.textSpotNode.position = position - self.textSpotNode.layer.animateScale(from: 0.3333, to: 10.5 + scaleAddition, duration: 0.55 + durationAddition, removeOnCompletion: false, completion: { _ in - textNode.view.mask = nil - }) - self.textSpotNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15) - - self.emitterNode.view.mask = self.emitterMaskNode.view - self.emitterSpotNode.frame = CGRect(x: 0.0, y: 0.0, width: self.emitterMaskNode.frame.width * 3.0, height: self.emitterMaskNode.frame.height * 3.0) - - self.emitterSpotNode.layer.anchorPoint = CGPoint(x: position.x / self.emitterMaskNode.frame.width, y: position.y / self.emitterMaskNode.frame.height) - self.emitterSpotNode.position = position - self.emitterSpotNode.layer.animateScale(from: 0.3333, to: 10.5 + scaleAddition, duration: 0.55 + durationAddition, removeOnCompletion: false, completion: { [weak self] _ in - self?.alpha = 0.0 - self?.emitterNode.view.mask = nil - - self?.emitter?.color = textColor.cgColor - }) - self.emitterMaskFillNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) - } - - Queue.mainQueue().after(0.8 * UIView.animationDurationFactor()) { - self.isExploding = false - self.emitterLayer?.setValue(false, forKeyPath: "emitterBehaviors.fingerAttractor.enabled") - self.textSpotNode.layer.removeAllAnimations() - - self.emitterSpotNode.layer.removeAllAnimations() - self.emitterMaskFillNode.layer.removeAllAnimations() + self.staticNode?.alpha = 0.0 + self.staticNode?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25) } } private func updateEmitter() { - guard let (size, color, _, _, wordRects) = self.currentParams else { + guard let (size, color, _, lineRects, wordRects) = self.currentParams else { return } - self.emitter?.color = self.animColor ?? color.cgColor - self.emitterLayer?.setValue(wordRects, forKey: "emitterRects") - self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size) - - let radius = max(size.width, size.height) - self.emitterLayer?.setValue(max(size.width, size.height), forKeyPath: "emitterBehaviors.fingerAttractor.radius") - self.emitterLayer?.setValue(radius * -0.5, forKeyPath: "emitterBehaviors.fingerAttractor.falloff") - - var square: Float = 0.0 - for rect in wordRects { - square += Float(rect.width * rect.height) - } - - Queue.mainQueue().async { - self.emitter?.birthRate = min(100000, square * 0.35) + if self.enableAnimations { + self.emitter?.color = self.animColor ?? color.cgColor + self.emitterLayer?.setValue(wordRects, forKey: "emitterRects") + self.emitterLayer?.frame = CGRect(origin: CGPoint(), size: size) + + let radius = max(size.width, size.height) + self.emitterLayer?.setValue(max(size.width, size.height), forKeyPath: "emitterBehaviors.fingerAttractor.radius") + self.emitterLayer?.setValue(radius * -0.5, forKeyPath: "emitterBehaviors.fingerAttractor.falloff") + + var square: Float = 0.0 + for rect in wordRects { + square += Float(rect.width * rect.height) + } + + Queue.mainQueue().async { + 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]) { self.currentParams = (size, color, textColor, rects, wordRects) - self.emitterNode.frame = CGRect(origin: CGPoint(), size: size) - self.emitterMaskNode.frame = self.emitterNode.bounds - self.emitterMaskFillNode.frame = self.emitterNode.bounds + let bounds = CGRect(origin: CGPoint(), size: size) + self.emitterNode.frame = bounds + self.emitterMaskNode.frame = bounds + self.emitterMaskFillNode.frame = bounds self.textMaskNode.frame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: size) + self.staticNode?.frame = bounds + if self.isNodeLoaded { self.updateEmitter() } diff --git a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift index 33cc6c6bf2..dcfd793e92 100644 --- a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift +++ b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift @@ -249,12 +249,6 @@ public func cacheAnimatedStickerFrames(data: Data, size: CGSize, fitzModifier: E subscriber.putNext(.tempFile(tempFile)) 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.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 { diff --git a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift index b01aed5fdc..c05dc97150 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift @@ -316,7 +316,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { if let current = strongSelf.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: nil) + dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency) dustNode.isUserInteractionEnabled = false strongSelf.dustNode = dustNode strongSelf.insertSubnode(dustNode, aboveSubnode: strongSelf.labelNode.textNode) diff --git a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift index d28819382a..662a37a751 100644 --- a/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift +++ b/submodules/TelegramUI/Sources/ChatMessageNotificationItem.swift @@ -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)) - 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 if let current = self.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: nil) + dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency) dustNode.isUserInteractionEnabled = false self.dustNode = dustNode self.insertSubnode(dustNode, aboveSubnode: self.textNode.textNode) diff --git a/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift index 52ae2d0986..1caa6a964a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageReplyInfoNode.swift @@ -344,7 +344,7 @@ class ChatMessageReplyInfoNode: ASDisplayNode { if let current = node.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: nil) + dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: arguments.context.sharedContext.energyUsageSettings.fullTranslucency) dustNode.isUserInteractionEnabled = false node.dustNode = dustNode node.contentNode.insertSubnode(dustNode, aboveSubnode: textNode.textNode) diff --git a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift index 37bfbae403..39a1affa5f 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift @@ -485,7 +485,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { if let current = strongSelf.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode) + dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode, enableAnimations: item.context.sharedContext.energyUsageSettings.fullTranslucency) strongSelf.dustNode = dustNode strongSelf.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode) } diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index a80e97f76d..9ace618b46 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -764,7 +764,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { if let current = strongSelf.dustNode { dustNode = current } else { - dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode) + dustNode = InvisibleInkDustNode(textNode: spoilerTextNode.textNode, enableAnimations: strongSelf.context.sharedContext.energyUsageSettings.fullTranslucency) strongSelf.dustNode = dustNode strongSelf.contentTextContainer.insertSubnode(dustNode, aboveSubnode: spoilerTextNode.textNode) } diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 8e83438a13..ef8aa6df89 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -2289,7 +2289,9 @@ 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) { let textRects = textInputNode.textView.selectionRects(for: textRange) for textRect in textRects { - rects.append(textRect.rect.insetBy(dx: 1.0, dy: 1.0).offsetBy(dx: 0.0, dy: 1.0)) + 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)) + } } } } @@ -2335,7 +2337,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { if let current = self.dustNode { dustNode = current } 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.isUserInteractionEnabled = false textInputNode.textView.addSubview(dustNode.view) diff --git a/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift b/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift index 836338c3ee..b5611154d7 100644 --- a/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift +++ b/submodules/TelegramUI/Sources/ReplyAccessoryPanelNode.swift @@ -34,6 +34,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode { private let actionArea: AccessibilityAreaNode + private let context: AccountContext var theme: PresentationTheme 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?) { self.messageId = messageId + self.context = context self.theme = theme self.strings = strings @@ -344,7 +346,7 @@ final class ReplyAccessoryPanelNode: AccessoryPanelNode { if let textLayout = self.textNode.cachedLayout, !textLayout.spoilers.isEmpty { if self.dustNode == nil { - let dustNode = InvisibleInkDustNode(textNode: nil) + let dustNode = InvisibleInkDustNode(textNode: nil, enableAnimations: self.context.sharedContext.energyUsageSettings.fullTranslucency) self.dustNode = dustNode self.textNode.supernode?.insertSubnode(dustNode, aboveSubnode: self.textNode) }