From bedf4289aefec178a4aebaa8030857cd98396aa9 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 14 Apr 2021 00:51:04 +0400 Subject: [PATCH] Update message animation --- .../ContextUI/Sources/ContextController.swift | 2 +- .../Source/ContextContentSourceNode.swift | 2 +- submodules/Display/Source/ListView.swift | 8 ++++---- .../Display/Source/ListViewItemNode.swift | 4 ++-- .../Sources/ChatMessageBackground.swift | 10 +--------- .../Sources/ChatMessageBubbleBackdrop.swift | 19 +++++-------------- .../Sources/ChatMessageBubbleItemNode.swift | 8 ++++---- .../Sources/ChatMessageTransitionNode.swift | 9 +++++++++ 8 files changed, 27 insertions(+), 35 deletions(-) diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index a31f2f4d01..b31b9d97d7 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -918,7 +918,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi intermediateCompletion() }) contentParentNode.updateAbsoluteRect?(self.contentContainerNode.frame.offsetBy(dx: 0.0, dy: -self.scrollNode.view.contentOffset.y + contentContainerOffset.y), self.bounds.size) - contentParentNode.applyAbsoluteOffset?(-contentContainerOffset.y, transitionCurve, transitionDuration) + contentParentNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: -contentContainerOffset.y), transitionCurve, transitionDuration) if let reactionContextNode = self.reactionContextNode { reactionContextNode.animateOut(to: CGRect(origin: CGPoint(x: originalProjectedContentViewFrame.1.minX, y: originalProjectedContentViewFrame.1.minY), size: contentParentNode.contentRect.size), animatingOutToReaction: self.reactionContextNodeIsAnimatingOut) diff --git a/submodules/Display/Source/ContextContentSourceNode.swift b/submodules/Display/Source/ContextContentSourceNode.swift index 145e0d1115..ffd7ab165e 100644 --- a/submodules/Display/Source/ContextContentSourceNode.swift +++ b/submodules/Display/Source/ContextContentSourceNode.swift @@ -11,7 +11,7 @@ public final class ContextExtractedContentContainingNode: ASDisplayNode { public var willUpdateIsExtractedToContextPreview: ((Bool, ContainedViewLayoutTransition) -> Void)? public var isExtractedToContextPreviewUpdated: ((Bool) -> Void)? public var updateAbsoluteRect: ((CGRect, CGSize) -> Void)? - public var applyAbsoluteOffset: ((CGFloat, ContainedViewLayoutTransitionCurve, Double) -> Void)? + public var applyAbsoluteOffset: ((CGPoint, ContainedViewLayoutTransitionCurve, Double) -> Void)? public var applyAbsoluteOffsetSpring: ((CGFloat, Double, CGFloat) -> Void)? public var layoutUpdated: ((CGSize) -> Void)? public var updateDistractionFreeMode: ((Bool) -> Void)? diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index ffbae84226..4ccff7b6a4 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -2826,7 +2826,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } self.layer.add(animation, forKey: nil) for itemNode in self.itemNodes { - itemNode.applyAbsoluteOffset(value: -completeOffset, animationCurve: animationCurve, duration: animationDuration) + itemNode.applyAbsoluteOffset(value: CGPoint(x: 0.0, y: -completeOffset), animationCurve: animationCurve, duration: animationDuration) } } } else { @@ -2866,7 +2866,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture springAnimation.isAdditive = true self.layer.add(springAnimation, forKey: nil) for itemNode in self.itemNodes { - itemNode.applyAbsoluteOffset(value: -completeOffset, animationCurve: .spring, duration: duration) + itemNode.applyAbsoluteOffset(value: CGPoint(x: 0.0, y: -completeOffset), animationCurve: .spring, duration: duration) } } else { if let snapshotView = snapshotView { @@ -3122,10 +3122,10 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } self.layer.add(animation, forKey: nil) for itemNode in self.itemNodes { - itemNode.applyAbsoluteOffset(value: -offset, animationCurve: animationCurve, duration: animationDuration) + itemNode.applyAbsoluteOffset(value: CGPoint(x: 0.0, y: -offset), animationCurve: animationCurve, duration: animationDuration) } for itemNode in temporaryPreviousNodes { - itemNode.applyAbsoluteOffset(value: -offset, animationCurve: animationCurve, duration: animationDuration) + itemNode.applyAbsoluteOffset(value: CGPoint(x: 0.0, y: -offset), animationCurve: animationCurve, duration: animationDuration) } if let verticalScrollIndicator = self.verticalScrollIndicator { verticalScrollIndicator.layer.add(reverseAnimation, forKey: nil) diff --git a/submodules/Display/Source/ListViewItemNode.swift b/submodules/Display/Source/ListViewItemNode.swift index d57694a912..0f1e3f992f 100644 --- a/submodules/Display/Source/ListViewItemNode.swift +++ b/submodules/Display/Source/ListViewItemNode.swift @@ -556,10 +556,10 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { } - open func applyAbsoluteOffset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + open func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { if let extractedBackgroundNode = self.extractedBackgroundNode { let transition: ContainedViewLayoutTransition = .animated(duration: duration, curve: animationCurve) - transition.animatePositionAdditive(node: extractedBackgroundNode, offset: CGPoint(x: 0.0, y: -value)) + transition.animatePositionAdditive(node: extractedBackgroundNode, offset: CGPoint(x: -value.x, y: -value.y)) } } diff --git a/submodules/TelegramUI/Sources/ChatMessageBackground.swift b/submodules/TelegramUI/Sources/ChatMessageBackground.swift index a482412157..0dab2ab676 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBackground.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBackground.swift @@ -241,15 +241,7 @@ class ChatMessageBackground: ASDisplayNode { self.view.addSubview(sourceView) - let wasMaskNode = self.maskMode - if let wasMaskNode = wasMaskNode, !wasMaskNode { - self.setMaskMode(true) - } - - sourceView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak self, weak sourceView] _ in - if let wasMaskNode = wasMaskNode, !wasMaskNode { - self?.setMaskMode(false) - } + sourceView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak sourceView] _ in sourceView?.removeFromSuperview() }) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleBackdrop.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleBackdrop.swift index 5873a521cf..842574b8b2 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleBackdrop.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleBackdrop.swift @@ -144,9 +144,9 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode { self.backgroundContent.frame = CGRect(origin: CGPoint(x: -rect.minX, y: -rect.minY), size: containerSize) } - func offset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + func offset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { let transition: ContainedViewLayoutTransition = .animated(duration: duration, curve: animationCurve) - transition.animatePositionAdditive(node: self.backgroundContent, offset: CGPoint(x: 0.0, y: -value)) + transition.animatePositionAdditive(node: self.backgroundContent, offset: CGPoint(x: -value.x, y: -value.y)) } func offsetSpring(value: CGFloat, duration: Double, damping: CGFloat) { @@ -164,20 +164,11 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode { func animateFrom(sourceView: UIView, mediaBox: MediaBox, transition: ContainedViewLayoutTransition) { if transition.isAnimated { - let wasMaskMode = self.currentMaskMode - if let wasMaskMode = wasMaskMode, !wasMaskMode { - self.fixedMaskMode = true - self.setMaskMode(true, mediaBox: mediaBox) - } - let previousFrame = self.frame self.updateFrame(CGRect(origin: previousFrame.origin, size: sourceView.frame.size), transition: .immediate) - self.updateFrame(previousFrame, transition: transition, completion: { [weak self] in - if let wasMaskMode = wasMaskMode, !wasMaskMode { - self?.fixedMaskMode = nil - self?.setMaskMode(false, mediaBox: mediaBox) - } - }) + self.updateFrame(previousFrame, transition: transition) + + self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 79eda5da6b..7d418890bc 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -245,7 +245,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode backgroundWallpaperNode.update(rect: mappedRect, within: containerSize) } - fileprivate func applyAbsoluteOffset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + fileprivate func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { guard let backgroundWallpaperNode = self.backgroundWallpaperNode else { return } @@ -3747,13 +3747,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode self.backgroundWallpaperNode.update(rect: mappedRect, within: containerSize) } - override func applyAbsoluteOffset(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + override func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { if !self.mainContextSourceNode.isExtractedToContextPreview { - self.applyAbsoluteOffsetInternal(value: -value, animationCurve: animationCurve, duration: duration) + self.applyAbsoluteOffsetInternal(value: CGPoint(x: -value.x, y: -value.y), animationCurve: animationCurve, duration: duration) } } - private func applyAbsoluteOffsetInternal(value: CGFloat, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + private func applyAbsoluteOffsetInternal(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { self.backgroundWallpaperNode.offset(value: value, animationCurve: animationCurve, duration: duration) } diff --git a/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift b/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift index 3a672f27c0..6f6efe5bdd 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift @@ -67,6 +67,9 @@ final class ChatMessageTransitionNode: ASDisplayNode { func beginAnimation() { switch self.source { case let .textInput(textInput, replyPanel): + self.contextSourceNode.isExtractedToContextPreview = true + self.contextSourceNode.isExtractedToContextPreviewUpdated?(true) + self.containerNode.addSubnode(self.contextSourceNode.contentNode) let targetAbsoluteRect = self.contextSourceNode.view.convert(self.contextSourceNode.contentRect, to: nil) @@ -96,17 +99,23 @@ final class ChatMessageTransitionNode: ASDisplayNode { } self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -self.contextSourceNode.contentRect.minX, dy: self.contextSourceNode.contentRect.minY) + self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size) self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.minY - targetAbsoluteRect.minY), to: CGPoint(), duration: duration, delay: delay, timingFunction: kCAMediaTimingFunctionSpring, additive: true, force: true, completion: { [weak self] _ in guard let strongSelf = self else { return } strongSelf.endAnimation() }) + self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), .spring, duration * 0.8) + self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.minY - targetAbsoluteRect.minY), .spring, duration) self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), to: CGPoint(), duration: duration * 0.8, delay: delay, timingFunction: kCAMediaTimingFunctionSpring, additive: true) } } private func endAnimation() { + self.contextSourceNode.isExtractedToContextPreview = false + self.contextSourceNode.isExtractedToContextPreviewUpdated?(false) + self.animationEnded?() }