mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Refactoring [skip ci]
This commit is contained in:
parent
76719a7c95
commit
8e566ed820
@ -383,6 +383,9 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/Chat/ChatSwipeToReplyRecognizer",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoItemNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageInstantVideoBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageAnimatedStickerItemNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageTransitionNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ManagedDiceAnimationNode",
|
||||
] + select({
|
||||
"@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets,
|
||||
"//build-system:ios_sim_arm64": [],
|
||||
|
@ -0,0 +1,60 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ChatMessageAnimatedStickerItemNode",
|
||||
module_name = "ChatMessageAnimatedStickerItemNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/MediaResources",
|
||||
"//submodules/StickerResources",
|
||||
"//submodules/ContextUI",
|
||||
"//submodules/AnimatedStickerNode",
|
||||
"//submodules/TelegramAnimatedStickerNode",
|
||||
"//submodules/Emoji",
|
||||
"//submodules/Markdown",
|
||||
"//submodules/ManagedAnimationNode",
|
||||
"//submodules/SlotMachineAnimationNode",
|
||||
"//submodules/MediaPlayer:UniversalMediaPlayer",
|
||||
"//submodules/ShimmerEffect",
|
||||
"//submodules/WallpaperBackgroundNode",
|
||||
"//submodules/LocalMediaResources",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/ChatPresentationInterfaceState",
|
||||
"//submodules/TelegramUI/Components/TextNodeWithEntities",
|
||||
"//submodules/TelegramUI/Components/ChatControllerInteraction",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageForwardInfoNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItem",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItemView",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageSwipeToReplyNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageSelectionNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageDeliveryFailedNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageShareButton",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatSwipeToReplyRecognizer",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageReactionsFooterContentNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ManagedDiceAnimationNode",
|
||||
"//submodules/TelegramUI/Components/Chat/MessageHaptics",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageTransitionNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
@ -43,12 +43,15 @@ import ChatMessageThreadInfoNode
|
||||
import ChatMessageActionButtonsNode
|
||||
import ChatSwipeToReplyRecognizer
|
||||
import ChatMessageReactionsFooterContentNode
|
||||
import ManagedDiceAnimationNode
|
||||
import MessageHaptics
|
||||
import ChatMessageTransitionNode
|
||||
|
||||
private let nameFont = Font.medium(14.0)
|
||||
private let inlineBotPrefixFont = Font.regular(14.0)
|
||||
private let inlineBotNameFont = nameFont
|
||||
|
||||
protocol GenericAnimatedStickerNode: ASDisplayNode {
|
||||
public protocol GenericAnimatedStickerNode: ASDisplayNode {
|
||||
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool)
|
||||
|
||||
var currentFrameIndex: Int { get }
|
||||
@ -56,29 +59,32 @@ protocol GenericAnimatedStickerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
extension DefaultAnimatedStickerNodeImpl: GenericAnimatedStickerNode {
|
||||
func setFrameIndex(_ frameIndex: Int) {
|
||||
public func setFrameIndex(_ frameIndex: Int) {
|
||||
self.stop()
|
||||
self.play(fromIndex: frameIndex)
|
||||
}
|
||||
}
|
||||
|
||||
extension SlotMachineAnimationNode: GenericAnimatedStickerNode {
|
||||
var currentFrameIndex: Int {
|
||||
public var currentFrameIndex: Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func setFrameIndex(_ frameIndex: Int) {
|
||||
public func setFrameIndex(_ frameIndex: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
let contextSourceNode: ContextExtractedContentContainingNode
|
||||
extension ManagedDiceAnimationNode: GenericAnimatedStickerNode {
|
||||
}
|
||||
|
||||
public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
public let contextSourceNode: ContextExtractedContentContainingNode
|
||||
private let containerNode: ContextControllerSourceNode
|
||||
let imageNode: TransformImageNode
|
||||
public let imageNode: TransformImageNode
|
||||
private var enableSynchronousImageApply: Bool = false
|
||||
private var backgroundNode: WallpaperBubbleBackgroundNode?
|
||||
private(set) var placeholderNode: StickerShimmerEffectNode
|
||||
private(set) var animationNode: GenericAnimatedStickerNode?
|
||||
public private(set) var placeholderNode: StickerShimmerEffectNode
|
||||
public private(set) var animationNode: GenericAnimatedStickerNode?
|
||||
private var animationSize: CGSize?
|
||||
private var didSetUpAnimationNode = false
|
||||
private var isPlaying = false
|
||||
@ -86,7 +92,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
private let textNode: TextNodeWithEntities
|
||||
|
||||
private var additionalAnimationNodes: [ChatMessageTransitionNode.DecorationItemNode] = []
|
||||
private var overlayMeshAnimationNode: ChatMessageTransitionNode.DecorationItemNode?
|
||||
private var enqueuedAdditionalAnimations: [(Int, Double)] = []
|
||||
private var additionalAnimationsCommitTimer: SwiftSignalKit.Timer?
|
||||
|
||||
@ -97,10 +102,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
private var deliveryFailedNode: ChatMessageDeliveryFailedNode?
|
||||
private var shareButtonNode: ChatMessageShareButton?
|
||||
|
||||
var telegramFile: TelegramMediaFile?
|
||||
var emojiFile: TelegramMediaFile?
|
||||
var telegramDice: TelegramMediaDice?
|
||||
var emojiString: String?
|
||||
public var telegramFile: TelegramMediaFile?
|
||||
public var emojiFile: TelegramMediaFile?
|
||||
public var telegramDice: TelegramMediaDice?
|
||||
public var emojiString: String?
|
||||
private let disposable = MetaDisposable()
|
||||
private let disposables = DisposableSet()
|
||||
|
||||
@ -136,7 +141,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
private var wasPending: Bool = false
|
||||
private var didChangeFromPendingToSent: Bool = false
|
||||
|
||||
required init() {
|
||||
required public init() {
|
||||
self.contextSourceNode = ContextExtractedContentContainingNode()
|
||||
self.containerNode = ContextControllerSourceNode()
|
||||
self.imageNode = TransformImageNode()
|
||||
@ -233,7 +238,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.additionalAnimationsCommitTimer?.invalidate()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@ -248,7 +253,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:)))
|
||||
@ -325,7 +330,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.view.addGestureRecognizer(replyRecognizer)
|
||||
}
|
||||
|
||||
override var visibility: ListViewItemNodeVisibility {
|
||||
override public var visibility: ListViewItemNodeVisibility {
|
||||
didSet {
|
||||
let wasVisible = oldValue != .none
|
||||
let isVisible = self.visibility != .none
|
||||
@ -425,7 +430,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) {
|
||||
override public func setupItem(_ item: ChatMessageItem, synchronousLoad: Bool) {
|
||||
super.setupItem(item, synchronousLoad: synchronousLoad)
|
||||
|
||||
if item.message.id.namespace == Namespaces.Message.Local || item.message.id.namespace == Namespaces.Message.ScheduledLocal {
|
||||
@ -587,13 +592,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
let isPlaying = self.visibilityStatus == true && !self.forceStopAnimations
|
||||
if !isPlaying {
|
||||
self.removeAdditionalAnimations()
|
||||
|
||||
if let overlayMeshAnimationNode = self.overlayMeshAnimationNode {
|
||||
self.overlayMeshAnimationNode = nil
|
||||
if let transitionNode = item.controllerInteraction.getMessageTransitionNode() as? ChatMessageTransitionNode {
|
||||
transitionNode.remove(decorationNode: overlayMeshAnimationNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let animationNode = self.animationNode as? AnimatedStickerNode {
|
||||
if self.isPlaying != isPlaying || (isPlaying && !self.didSetUpAnimationNode) {
|
||||
@ -663,13 +661,13 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func updateStickerSettings(forceStopAnimations: Bool) {
|
||||
override public func updateStickerSettings(forceStopAnimations: Bool) {
|
||||
self.forceStopAnimations = forceStopAnimations
|
||||
self.updateVisibility()
|
||||
}
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
self.absoluteRect = (rect, containerSize)
|
||||
if !self.contextSourceNode.isExtractedToContextPreview {
|
||||
var rect = rect
|
||||
@ -723,7 +721,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
|
||||
override public func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
|
||||
if let backgroundNode = self.backgroundNode {
|
||||
backgroundNode.offset(value: value, animationCurve: animationCurve, duration: duration)
|
||||
}
|
||||
@ -733,7 +731,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) {
|
||||
override public func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) {
|
||||
super.updateAccessibilityData(accessibilityData)
|
||||
|
||||
self.messageAccessibilityArea.accessibilityLabel = accessibilityData.label
|
||||
@ -764,7 +762,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) {
|
||||
override public func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, ListViewItemApply, Bool) -> Void) {
|
||||
var displaySize = CGSize(width: 180.0, height: 180.0)
|
||||
let telegramFile = self.telegramFile
|
||||
let emojiFile = self.emojiFile
|
||||
@ -1761,7 +1759,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
item.controllerInteraction.commitEmojiInteraction(item.message.id, item.message.text.strippedEmoji, EmojiInteraction(animations: animations), file)
|
||||
}
|
||||
|
||||
func playEmojiInteraction(_ interaction: EmojiInteraction) {
|
||||
public func playEmojiInteraction(_ interaction: EmojiInteraction) {
|
||||
guard interaction.animations.count <= 7 else {
|
||||
return
|
||||
}
|
||||
@ -1807,7 +1805,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
func playAdditionalEmojiAnimation(index: Int) {
|
||||
public func playAdditionalEmojiAnimation(index: Int) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
@ -1846,7 +1844,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
self.playEffectAnimation(resource: effect.resource, isStickerEffect: true)
|
||||
}
|
||||
|
||||
func playEffectAnimation(resource: MediaResource, isStickerEffect: Bool = false) {
|
||||
public func playEffectAnimation(resource: MediaResource, isStickerEffect: Bool = false) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
@ -2282,7 +2280,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
|
||||
private var playedSwipeToReplyHaptic = false
|
||||
@objc func swipeToReplyGesture(_ recognizer: ChatSwipeToReplyRecognizer) {
|
||||
@objc private func swipeToReplyGesture(_ recognizer: ChatSwipeToReplyRecognizer) {
|
||||
var offset: CGFloat = 0.0
|
||||
var leftOffset: CGFloat = 0.0
|
||||
var swipeOffset: CGFloat = 45.0
|
||||
@ -2406,7 +2404,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if let shareButtonNode = self.shareButtonNode, shareButtonNode.frame.contains(point) {
|
||||
return shareButtonNode.view
|
||||
}
|
||||
@ -2421,7 +2419,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
|
||||
override func updateSelectionState(animated: Bool) {
|
||||
override public func updateSelectionState(animated: Bool) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
@ -2503,7 +2501,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func updateHighlightedState(animated: Bool) {
|
||||
override public func updateHighlightedState(animated: Bool) {
|
||||
super.updateHighlightedState(animated: animated)
|
||||
|
||||
if let item = self.item {
|
||||
@ -2528,11 +2526,11 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func cancelInsertionAnimations() {
|
||||
override public func cancelInsertionAnimations() {
|
||||
self.layer.removeAllAnimations()
|
||||
}
|
||||
|
||||
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
override public func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||
super.animateInsertion(currentTimestamp, duration: duration, short: short)
|
||||
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
@ -2550,27 +2548,41 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
override public func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||
super.animateRemoved(currentTimestamp, duration: duration)
|
||||
|
||||
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
override func animateAdded(_ currentTimestamp: Double, duration: Double) {
|
||||
override public func animateAdded(_ currentTimestamp: Double, duration: Double) {
|
||||
super.animateAdded(currentTimestamp, duration: duration)
|
||||
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
|
||||
override func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? {
|
||||
override public func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? {
|
||||
return self.contextSourceNode
|
||||
}
|
||||
|
||||
override func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) {
|
||||
override public func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) {
|
||||
self.contextSourceNode.contentNode.addSubnode(accessoryItemNode)
|
||||
}
|
||||
|
||||
public final class AnimationTransitionTextInput {
|
||||
public let backgroundView: UIView
|
||||
public let contentView: UIView
|
||||
public let sourceRect: CGRect
|
||||
public let scrollOffset: CGFloat
|
||||
|
||||
func animateContentFromTextInputField(textInput: ChatMessageTransitionNode.Source.TextInput, transition: CombinedTransition) {
|
||||
public init(backgroundView: UIView, contentView: UIView, sourceRect: CGRect, scrollOffset: CGFloat) {
|
||||
self.backgroundView = backgroundView
|
||||
self.contentView = contentView
|
||||
self.sourceRect = sourceRect
|
||||
self.scrollOffset = scrollOffset
|
||||
}
|
||||
}
|
||||
|
||||
public func animateContentFromTextInputField(textInput: AnimationTransitionTextInput, transition: CombinedTransition) {
|
||||
guard let _ = self.item else {
|
||||
return
|
||||
}
|
||||
@ -2629,8 +2641,56 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
self.dateAndStatusNode.layer.animateAlpha(from: 0.0, to: self.dateAndStatusNode.alpha, duration: 0.15, delay: 0.16)
|
||||
}
|
||||
|
||||
public final class AnimationTransitionSticker {
|
||||
public let imageNode: TransformImageNode?
|
||||
public let animationNode: ASDisplayNode?
|
||||
public let placeholderNode: ASDisplayNode?
|
||||
public let imageLayer: CALayer?
|
||||
public let relativeSourceRect: CGRect
|
||||
|
||||
var sourceFrame: CGRect {
|
||||
if let imageNode = self.imageNode {
|
||||
return imageNode.frame
|
||||
} else if let imageLayer = self.imageLayer {
|
||||
return imageLayer.bounds
|
||||
} else {
|
||||
return CGRect(origin: CGPoint(), size: relativeSourceRect.size)
|
||||
}
|
||||
}
|
||||
|
||||
var sourceLayer: CALayer? {
|
||||
if let imageNode = self.imageNode {
|
||||
return imageNode.layer
|
||||
} else if let imageLayer = self.imageLayer {
|
||||
return imageLayer
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func snapshotContentTree() -> UIView? {
|
||||
if let animationNode = self.animationNode {
|
||||
return animationNode.view.snapshotContentTree()
|
||||
} else if let imageNode = self.imageNode {
|
||||
return imageNode.view.snapshotContentTree()
|
||||
} else if let sourceLayer = self.imageLayer {
|
||||
return sourceLayer.snapshotContentTreeAsView()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public init(imageNode: TransformImageNode?, animationNode: ASDisplayNode?, placeholderNode: ASDisplayNode?, imageLayer: CALayer?, relativeSourceRect: CGRect) {
|
||||
self.imageNode = imageNode
|
||||
self.animationNode = animationNode
|
||||
self.placeholderNode = placeholderNode
|
||||
self.imageLayer = imageLayer
|
||||
self.relativeSourceRect = relativeSourceRect
|
||||
}
|
||||
}
|
||||
|
||||
func animateContentFromStickerGridItem(stickerSource: ChatMessageTransitionNode.Sticker, transition: CombinedTransition) {
|
||||
public func animateContentFromStickerGridItem(stickerSource: AnimationTransitionSticker, transition: CombinedTransition) {
|
||||
guard let _ = self.item else {
|
||||
return
|
||||
}
|
||||
@ -2716,8 +2776,26 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
placeholderNode.layer.animateAlpha(from: 0.0, to: placeholderNode.alpha, duration: 0.4)
|
||||
}
|
||||
}
|
||||
|
||||
public final class AnimationTransitionReplyPanel {
|
||||
public let titleNode: ASDisplayNode
|
||||
public let textNode: ASDisplayNode
|
||||
public let lineNode: ASDisplayNode
|
||||
public let imageNode: ASDisplayNode
|
||||
public let relativeSourceRect: CGRect
|
||||
public let relativeTargetRect: CGRect
|
||||
|
||||
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNode.ReplyPanel, transition: CombinedTransition) {
|
||||
public init(titleNode: ASDisplayNode, textNode: ASDisplayNode, lineNode: ASDisplayNode, imageNode: ASDisplayNode, relativeSourceRect: CGRect, relativeTargetRect: CGRect) {
|
||||
self.titleNode = titleNode
|
||||
self.textNode = textNode
|
||||
self.lineNode = lineNode
|
||||
self.imageNode = imageNode
|
||||
self.relativeSourceRect = relativeSourceRect
|
||||
self.relativeTargetRect = relativeTargetRect
|
||||
}
|
||||
}
|
||||
|
||||
public func animateReplyPanel(sourceReplyPanel: AnimationTransitionReplyPanel, transition: CombinedTransition) {
|
||||
if let replyInfoNode = self.replyInfoNode {
|
||||
let localRect = self.contextSourceNode.contentNode.view.convert(sourceReplyPanel.relativeSourceRect, to: replyInfoNode.view)
|
||||
|
||||
@ -2737,7 +2815,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) {
|
||||
public func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
@ -2747,14 +2825,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
transition.animateTransformScale(node: self, from: CGPoint(x: 0.85, y: 0.85), delay: delay)
|
||||
}
|
||||
|
||||
override func openMessageContextMenu() {
|
||||
override public func openMessageContextMenu() {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
item.controllerInteraction.openMessageContextMenu(item.message, false, self, self.imageNode.frame, nil, nil)
|
||||
}
|
||||
|
||||
override func targetReactionView(value: MessageReaction.Reaction) -> UIView? {
|
||||
override public func targetReactionView(value: MessageReaction.Reaction) -> UIView? {
|
||||
if let result = self.reactionButtonsNode?.reactionTargetView(value: value) {
|
||||
return result
|
||||
}
|
||||
@ -2764,7 +2842,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
return nil
|
||||
}
|
||||
|
||||
override func targetForStoryTransition(id: StoryId) -> UIView? {
|
||||
override public func targetForStoryTransition(id: StoryId) -> UIView? {
|
||||
guard let item = self.item else {
|
||||
return nil
|
||||
}
|
||||
@ -2780,17 +2858,17 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
return nil
|
||||
}
|
||||
|
||||
override func unreadMessageRangeUpdated() {
|
||||
override public func unreadMessageRangeUpdated() {
|
||||
self.updateVisibility()
|
||||
}
|
||||
|
||||
override func contentFrame() -> CGRect {
|
||||
override public func contentFrame() -> CGRect {
|
||||
return self.imageNode.frame
|
||||
}
|
||||
}
|
||||
|
||||
struct AnimatedEmojiSoundsConfiguration {
|
||||
static var defaultValue: AnimatedEmojiSoundsConfiguration {
|
||||
public struct AnimatedEmojiSoundsConfiguration {
|
||||
public static var defaultValue: AnimatedEmojiSoundsConfiguration {
|
||||
return AnimatedEmojiSoundsConfiguration(sounds: [:])
|
||||
}
|
||||
|
||||
@ -2800,7 +2878,7 @@ struct AnimatedEmojiSoundsConfiguration {
|
||||
self.sounds = sounds
|
||||
}
|
||||
|
||||
static func with(appConfiguration: AppConfiguration, account: Account) -> AnimatedEmojiSoundsConfiguration {
|
||||
public static func with(appConfiguration: AppConfiguration, account: Account) -> AnimatedEmojiSoundsConfiguration {
|
||||
if let data = appConfiguration.data, let values = data["emojies_sounds"] as? [String: Any] {
|
||||
var sounds: [String: TelegramMediaFile] = [:]
|
||||
for (key, value) in values {
|
@ -0,0 +1,19 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ChatMessageTransitionNode",
|
||||
module_name = "ChatMessageTransitionNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageItemView",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import ChatMessageItemView
|
||||
import AsyncDisplayKit
|
||||
|
||||
public protocol ChatMessageTransitionNodeDecorationItemNode: ASDisplayNode {
|
||||
var contentView: UIView { get }
|
||||
}
|
||||
|
||||
public protocol ChatMessageTransitionNode: AnyObject {
|
||||
typealias DecorationItemNode = ChatMessageTransitionNodeDecorationItemNode
|
||||
|
||||
func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode
|
||||
func remove(decorationNode: DecorationItemNode)
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ManagedDiceAnimationNode",
|
||||
module_name = "ManagedDiceAnimationNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/Display",
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/StickerResources",
|
||||
"//submodules/ManagedAnimationNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
@ -8,7 +8,7 @@ import AccountContext
|
||||
import StickerResources
|
||||
import ManagedAnimationNode
|
||||
|
||||
enum ManagedDiceAnimationState: Equatable {
|
||||
public enum ManagedDiceAnimationState: Equatable {
|
||||
case rolling
|
||||
case value(Int32, Bool)
|
||||
}
|
||||
@ -86,7 +86,7 @@ private struct InteractiveEmojiSuccessParameters {
|
||||
}
|
||||
|
||||
public struct InteractiveEmojiConfiguration {
|
||||
static var defaultValue: InteractiveEmojiConfiguration {
|
||||
public static var defaultValue: InteractiveEmojiConfiguration {
|
||||
return InteractiveEmojiConfiguration(emojis: [], successParameters: [:])
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ public struct InteractiveEmojiConfiguration {
|
||||
self.successParameters = successParameters
|
||||
}
|
||||
|
||||
static func with(appConfiguration: AppConfiguration) -> InteractiveEmojiConfiguration {
|
||||
public static func with(appConfiguration: AppConfiguration) -> InteractiveEmojiConfiguration {
|
||||
if let data = appConfiguration.data, let emojis = data["emojies_send_dice"] as? [String] {
|
||||
var successParameters: [String: InteractiveEmojiSuccessParameters] = [:]
|
||||
if let success = data["emojies_send_dice_success"] as? [String: [String: Double]] {
|
||||
@ -115,7 +115,7 @@ public struct InteractiveEmojiConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStickerNode {
|
||||
public final class ManagedDiceAnimationNode: ManagedAnimationNode {
|
||||
private let context: AccountContext
|
||||
private let emoji: String
|
||||
|
||||
@ -125,9 +125,9 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
private let configuration = Promise<InteractiveEmojiConfiguration?>()
|
||||
private let emojis = Promise<[TelegramMediaFile]>()
|
||||
|
||||
var success: (() -> Void)?
|
||||
public var success: (() -> Void)?
|
||||
|
||||
init(context: AccountContext, emoji: String) {
|
||||
public init(context: AccountContext, emoji: String) {
|
||||
self.context = context
|
||||
self.emoji = emoji
|
||||
|
||||
@ -157,7 +157,7 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
self.disposable.dispose()
|
||||
}
|
||||
|
||||
func setState(_ diceState: ManagedDiceAnimationState) {
|
||||
public func setState(_ diceState: ManagedDiceAnimationState) {
|
||||
let previousState = self.diceState
|
||||
self.diceState = diceState
|
||||
|
||||
@ -203,13 +203,13 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
||||
}
|
||||
}
|
||||
|
||||
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool) {
|
||||
public func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool) {
|
||||
}
|
||||
|
||||
func setFrameIndex(_ frameIndex: Int) {
|
||||
public func setFrameIndex(_ frameIndex: Int) {
|
||||
}
|
||||
|
||||
var currentFrameIndex: Int {
|
||||
public var currentFrameIndex: Int {
|
||||
return 0
|
||||
}
|
||||
}
|
19
submodules/TelegramUI/Components/Chat/MessageHaptics/BUILD
Normal file
19
submodules/TelegramUI/Components/Chat/MessageHaptics/BUILD
Normal file
@ -0,0 +1,19 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "MessageHaptics",
|
||||
module_name = "MessageHaptics",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/Display",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
@ -5,11 +5,11 @@ import SwiftSignalKit
|
||||
private let firstImpactTime: Double = 0.4
|
||||
private let secondImpactTime: Double = 0.6
|
||||
|
||||
final class CoffinHaptic: EmojiHaptic {
|
||||
public final class CoffinHaptic: EmojiHaptic {
|
||||
private var hapticFeedback = HapticFeedback()
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
private var time: Double = 0.0
|
||||
var enabled: Bool = false {
|
||||
public var enabled: Bool = false {
|
||||
didSet {
|
||||
if !self.enabled {
|
||||
self.reset()
|
||||
@ -17,9 +17,12 @@ final class CoffinHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
var active: Bool {
|
||||
public var active: Bool {
|
||||
return self.timer != nil
|
||||
}
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
private func reset() {
|
||||
if let timer = self.timer {
|
||||
@ -36,7 +39,7 @@ final class CoffinHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
func start(time: Double) {
|
||||
public func start(time: Double) {
|
||||
self.hapticFeedback.prepareImpact()
|
||||
|
||||
if time > firstImpactTime {
|
@ -2,18 +2,18 @@ import Foundation
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
|
||||
protocol EmojiHaptic {
|
||||
public protocol EmojiHaptic {
|
||||
var enabled: Bool { get set }
|
||||
var active: Bool { get }
|
||||
|
||||
func start(time: Double)
|
||||
}
|
||||
|
||||
final class HeartbeatHaptic: EmojiHaptic {
|
||||
public final class HeartbeatHaptic: EmojiHaptic {
|
||||
private var hapticFeedback = HapticFeedback()
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
private var time: Double = 0.0
|
||||
var enabled: Bool = false {
|
||||
public var enabled: Bool = false {
|
||||
didSet {
|
||||
if !self.enabled {
|
||||
self.reset()
|
||||
@ -21,9 +21,12 @@ final class HeartbeatHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
var active: Bool {
|
||||
public var active: Bool {
|
||||
return self.timer != nil
|
||||
}
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
private func reset() {
|
||||
if let timer = self.timer {
|
||||
@ -42,7 +45,7 @@ final class HeartbeatHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
func start(time: Double) {
|
||||
public func start(time: Double) {
|
||||
self.hapticFeedback.prepareImpact()
|
||||
|
||||
if time > 2.0 {
|
@ -4,11 +4,11 @@ import SwiftSignalKit
|
||||
|
||||
private let impactTime: Double = 0.6
|
||||
|
||||
final class PeachHaptic: EmojiHaptic {
|
||||
public final class PeachHaptic: EmojiHaptic {
|
||||
private var hapticFeedback = HapticFeedback()
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
private var time: Double = 0.0
|
||||
var enabled: Bool = false {
|
||||
public var enabled: Bool = false {
|
||||
didSet {
|
||||
if !self.enabled {
|
||||
self.reset()
|
||||
@ -16,9 +16,12 @@ final class PeachHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
var active: Bool {
|
||||
public var active: Bool {
|
||||
return self.timer != nil
|
||||
}
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
private func reset() {
|
||||
if let timer = self.timer {
|
||||
@ -35,7 +38,7 @@ final class PeachHaptic: EmojiHaptic {
|
||||
}
|
||||
}
|
||||
|
||||
func start(time: Double) {
|
||||
public func start(time: Double) {
|
||||
self.hapticFeedback.prepareImpact()
|
||||
|
||||
if time > impactTime {
|
@ -110,6 +110,7 @@ import ChatMessagePollBubbleContentNode
|
||||
import ChatMessageItem
|
||||
import ChatMessageItemView
|
||||
import ChatMessageItemCommon
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
|
||||
public enum ChatControllerPeekActions {
|
||||
case standard
|
||||
@ -8089,9 +8090,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
} else {
|
||||
isScheduledMessages = false
|
||||
}
|
||||
let duration: Double = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.animationDuration : 0.18
|
||||
let curve: ContainedViewLayoutTransitionCurve = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.verticalAnimationCurve : .easeInOut
|
||||
let controlPoints: (Float, Float, Float, Float) = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNode.verticalAnimationControlPoints : (0.5, 0.33, 0.0, 0.0)
|
||||
let duration: Double = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.animationDuration : 0.18
|
||||
let curve: ContainedViewLayoutTransitionCurve = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.verticalAnimationCurve : .easeInOut
|
||||
let controlPoints: (Float, Float, Float, Float) = strongSelf.chatDisplayNode.messageTransitionNode.hasScheduledTransitions ? ChatMessageTransitionNodeImpl.verticalAnimationControlPoints : (0.5, 0.33, 0.0, 0.0)
|
||||
|
||||
let shouldUseFastMessageSendAnimation = strongSelf.chatDisplayNode.shouldUseFastMessageSendAnimation
|
||||
|
||||
@ -15533,15 +15534,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
if addedTransitions.count > 1 {
|
||||
var transitions: [(Int64, ChatMessageTransitionNode.Source, () -> Void)] = []
|
||||
var transitions: [(Int64, ChatMessageTransitionNodeImpl.Source, () -> Void)] = []
|
||||
for (correlationId, uniqueIds, initiated) in addedTransitions {
|
||||
var source: ChatMessageTransitionNode.Source?
|
||||
var source: ChatMessageTransitionNodeImpl.Source?
|
||||
if uniqueIds.count > 1 {
|
||||
source = .groupedMediaInput(ChatMessageTransitionNode.Source.GroupedMediaInput(extractSnapshots: {
|
||||
source = .groupedMediaInput(ChatMessageTransitionNodeImpl.Source.GroupedMediaInput(extractSnapshots: {
|
||||
return uniqueIds.compactMap({ getAnimatedTransitionSource?($0) })
|
||||
}))
|
||||
} else if let uniqueId = uniqueIds.first {
|
||||
source = .mediaInput(ChatMessageTransitionNode.Source.MediaInput(extractSnapshot: {
|
||||
source = .mediaInput(ChatMessageTransitionNodeImpl.Source.MediaInput(extractSnapshot: {
|
||||
return getAnimatedTransitionSource?(uniqueId)
|
||||
}))
|
||||
}
|
||||
@ -15551,13 +15552,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.add(grouped: transitions)
|
||||
} else if let (correlationId, uniqueIds, initiated) = addedTransitions.first {
|
||||
var source: ChatMessageTransitionNode.Source?
|
||||
var source: ChatMessageTransitionNodeImpl.Source?
|
||||
if uniqueIds.count > 1 {
|
||||
source = .groupedMediaInput(ChatMessageTransitionNode.Source.GroupedMediaInput(extractSnapshots: {
|
||||
source = .groupedMediaInput(ChatMessageTransitionNodeImpl.Source.GroupedMediaInput(extractSnapshots: {
|
||||
return uniqueIds.compactMap({ getAnimatedTransitionSource?($0) })
|
||||
}))
|
||||
} else if let uniqueId = uniqueIds.first {
|
||||
source = .mediaInput(ChatMessageTransitionNode.Source.MediaInput(extractSnapshot: {
|
||||
source = .mediaInput(ChatMessageTransitionNodeImpl.Source.MediaInput(extractSnapshot: {
|
||||
return getAnimatedTransitionSource?(uniqueId)
|
||||
}))
|
||||
}
|
||||
@ -15825,7 +15826,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
if strongSelf.chatDisplayNode.shouldAnimateMessageTransition, let extractedView = videoController.extractVideoSnapshot() {
|
||||
usedCorrelationId = true
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .videoMessage(ChatMessageTransitionNode.Source.VideoMessage(view: extractedView)), initiated: { [weak videoController] in
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .videoMessage(ChatMessageTransitionNodeImpl.Source.VideoMessage(view: extractedView)), initiated: { [weak videoController] in
|
||||
videoController?.hideVideoSnapshot()
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -15937,7 +15938,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
if strongSelf.chatDisplayNode.shouldAnimateMessageTransition, let textInputPanelNode = strongSelf.chatDisplayNode.textInputPanelNode, let micButton = textInputPanelNode.micButton {
|
||||
usedCorrelationId = true
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .audioMicInput(ChatMessageTransitionNode.Source.AudioMicInput(micButton: micButton)), initiated: {
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.add(correlationId: correlationId, source: .audioMicInput(ChatMessageTransitionNodeImpl.Source.AudioMicInput(micButton: micButton)), initiated: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ import TextSelectionNode
|
||||
import ReplyAccessoryPanelNode
|
||||
import ChatMessageItemView
|
||||
import ChatMessageSelectionNode
|
||||
import ManagedDiceAnimationNode
|
||||
import ChatMessageTransitionNode
|
||||
|
||||
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
|
||||
let itemNode: OverlayMediaItemNode
|
||||
@ -267,7 +269,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
private var dropDimNode: ASDisplayNode?
|
||||
|
||||
let messageTransitionNode: ChatMessageTransitionNode
|
||||
let messageTransitionNode: ChatMessageTransitionNodeImpl
|
||||
|
||||
private let presentationContextMarker = ASDisplayNode()
|
||||
|
||||
@ -589,7 +591,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
source = .default
|
||||
}
|
||||
|
||||
var getMessageTransitionNode: (() -> ChatMessageTransitionNode?)?
|
||||
var getMessageTransitionNode: (() -> ChatMessageTransitionNodeImpl?)?
|
||||
self.historyNode = ChatHistoryListNode(context: context, updatedPresentationData: controller?.updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tagMask: nil, source: source, subject: subject, controllerInteraction: controllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), messageTransitionNode: {
|
||||
return getMessageTransitionNode?()
|
||||
})
|
||||
@ -605,7 +607,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
var getContentAreaInScreenSpaceImpl: (() -> CGRect)?
|
||||
var onTransitionEventImpl: ((ContainedViewLayoutTransition) -> Void)?
|
||||
self.messageTransitionNode = ChatMessageTransitionNode(listNode: self.historyNode, getContentAreaInScreenSpace: {
|
||||
self.messageTransitionNode = ChatMessageTransitionNodeImpl(listNode: self.historyNode, getContentAreaInScreenSpace: {
|
||||
return getContentAreaInScreenSpaceImpl?() ?? CGRect()
|
||||
}, onTransitionEvent: { transition in
|
||||
onTransitionEventImpl?(transition)
|
||||
@ -3472,7 +3474,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
if self.shouldAnimateMessageTransition, let inputPanelNode = self.inputPanelNode as? ChatTextInputPanelNode, let textInput = inputPanelNode.makeSnapshotForTransition() {
|
||||
usedCorrelationId = correlationId
|
||||
let source: ChatMessageTransitionNode.Source = .textInput(textInput: textInput, replyPanel: replyPanel)
|
||||
let source: ChatMessageTransitionNodeImpl.Source = .textInput(textInput: textInput, replyPanel: replyPanel)
|
||||
self.messageTransitionNode.add(correlationId: correlationId, source: source, initiated: {
|
||||
})
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import ChatOverscrollControl
|
||||
import ChatBotInfoItem
|
||||
import ChatMessageItem
|
||||
import ChatMessageItemView
|
||||
import ChatMessageTransitionNode
|
||||
|
||||
struct ChatTopVisibleMessageRange: Equatable {
|
||||
var lowerBound: MessageIndex
|
||||
@ -662,7 +663,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
private var toLang: String?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNode? = { nil }) {
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl? = { nil }) {
|
||||
var tagMask = tagMask
|
||||
if case .pinnedMessages = subject {
|
||||
tagMask = .pinned
|
||||
@ -1015,7 +1016,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
private func beginChatHistoryTransitions(
|
||||
selectedMessages: Signal<Set<MessageId>?, NoError>,
|
||||
messageTransitionNode: @escaping () -> ChatMessageTransitionNode?
|
||||
messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?
|
||||
) {
|
||||
let context = self.context
|
||||
let chatLocation = self.chatLocation
|
||||
|
@ -14,6 +14,7 @@ import ChatMessageItem
|
||||
import ChatMessageItemView
|
||||
import ChatMessageStickerItemNode
|
||||
import ChatMessageInstantVideoItemNode
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
|
||||
final class ChatLoadingNode: ASDisplayNode {
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
|
@ -851,7 +851,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
transition.animateTransformScale(node: self, from: CGPoint(x: 0.85, y: 0.85), delay: delay)
|
||||
}
|
||||
|
||||
func animateContentFromTextInputField(textInput: ChatMessageTransitionNode.Source.TextInput, transition: CombinedTransition) {
|
||||
func animateContentFromTextInputField(textInput: ChatMessageTransitionNodeImpl.Source.TextInput, transition: CombinedTransition) {
|
||||
let widthDifference = self.backgroundNode.frame.width - textInput.backgroundView.frame.width
|
||||
let heightDifference = self.backgroundNode.frame.height - textInput.backgroundView.frame.height
|
||||
|
||||
@ -884,7 +884,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
}
|
||||
|
||||
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNode.ReplyPanel, transition: CombinedTransition) {
|
||||
func animateReplyPanel(sourceReplyPanel: ChatMessageTransitionNodeImpl.ReplyPanel, transition: CombinedTransition) {
|
||||
if let replyInfoNode = self.replyInfoNode {
|
||||
let localRect = self.mainContextSourceNode.contentNode.view.convert(sourceReplyPanel.relativeSourceRect, to: replyInfoNode.view)
|
||||
let mappedPanel = ChatMessageReplyInfoNode.TransitionReplyPanel(
|
||||
|
@ -15,6 +15,7 @@ import ChatHistoryEntry
|
||||
import ChatMessageItem
|
||||
import ChatMessageItemView
|
||||
import ChatMessageStickerItemNode
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
|
||||
private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge {
|
||||
if let story = media as? TelegramMediaStory, story.isMention {
|
||||
|
@ -16,6 +16,8 @@ import ReplyAccessoryPanelNode
|
||||
import ChatMessageItemView
|
||||
import ChatMessageStickerItemNode
|
||||
import ChatMessageInstantVideoItemNode
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
import ChatMessageTransitionNode
|
||||
|
||||
private func convertAnimatingSourceRect(_ rect: CGRect, fromView: UIView, toView: UIView?) -> CGRect {
|
||||
if let presentationLayer = fromView.layer.presentation() {
|
||||
@ -100,7 +102,7 @@ private final class OverlayTransitionContainerController: ViewController, Standa
|
||||
}
|
||||
}
|
||||
|
||||
public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransitionProtocol {
|
||||
public final class ChatMessageTransitionNodeImpl: ASDisplayNode, ChatMessageTransitionNode, ChatMessageTransitionProtocol {
|
||||
static let animationDuration: Double = 0.3
|
||||
|
||||
static let verticalAnimationControlPoints: (Float, Float, Float, Float) = (0.19919472913616398, 0.010644531250000006, 0.27920937042459737, 0.91025390625)
|
||||
@ -235,7 +237,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
case groupedMediaInput(GroupedMediaInput)
|
||||
}
|
||||
|
||||
final class DecorationItemNode: ASDisplayNode {
|
||||
final class DecorationItemNodeImpl: ASDisplayNode, ChatMessageTransitionNode.DecorationItemNode {
|
||||
let itemNode: ChatMessageItemView
|
||||
let contentView: UIView
|
||||
private let getContentAreaInScreenSpace: () -> CGRect
|
||||
@ -288,7 +290,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
private final class AnimatingItemNode: ASDisplayNode {
|
||||
let itemNode: ChatMessageItemView
|
||||
private let contextSourceNode: ContextExtractedContentContainingNode
|
||||
private let source: ChatMessageTransitionNode.Source
|
||||
private let source: ChatMessageTransitionNodeImpl.Source
|
||||
private let getContentAreaInScreenSpace: () -> CGRect
|
||||
|
||||
private let scrollingContainer: ASDisplayNode
|
||||
@ -300,7 +302,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
var animationEnded: (() -> Void)?
|
||||
var updateAfterCompletion: Bool = false
|
||||
|
||||
init(itemNode: ChatMessageItemView, contextSourceNode: ContextExtractedContentContainingNode, source: ChatMessageTransitionNode.Source, getContentAreaInScreenSpace: @escaping () -> CGRect) {
|
||||
init(itemNode: ChatMessageItemView, contextSourceNode: ContextExtractedContentContainingNode, source: ChatMessageTransitionNodeImpl.Source, getContentAreaInScreenSpace: @escaping () -> CGRect) {
|
||||
self.itemNode = itemNode
|
||||
self.getContentAreaInScreenSpace = getContentAreaInScreenSpace
|
||||
|
||||
@ -328,7 +330,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
}
|
||||
|
||||
func beginAnimation() {
|
||||
let verticalDuration: Double = ChatMessageTransitionNode.animationDuration
|
||||
let verticalDuration: Double = ChatMessageTransitionNodeImpl.animationDuration
|
||||
let horizontalDuration: Double = verticalDuration
|
||||
let delay: Double = 0.0
|
||||
|
||||
@ -367,7 +369,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
let sourceBackgroundAbsoluteRect = initialTextInput.backgroundView.frame.offsetBy(dx: sourceRect.minX, dy: sourceRect.minY)
|
||||
let sourceAbsoluteRect = CGRect(origin: CGPoint(x: sourceBackgroundAbsoluteRect.minX, y: sourceBackgroundAbsoluteRect.maxY - self.contextSourceNode.contentRect.height), size: self.contextSourceNode.contentRect.size)
|
||||
|
||||
let textInput = ChatMessageTransitionNode.Source.TextInput(backgroundView: initialTextInput.backgroundView, contentView: initialTextInput.contentView, sourceRect: sourceRect, scrollOffset: initialTextInput.scrollOffset)
|
||||
let textInput = ChatMessageTransitionNodeImpl.Source.TextInput(backgroundView: initialTextInput.backgroundView, contentView: initialTextInput.contentView, sourceRect: sourceRect, scrollOffset: initialTextInput.scrollOffset)
|
||||
|
||||
textInput.backgroundView.frame = CGRect(origin: CGPoint(x: 0.0, y: sourceAbsoluteRect.height - sourceBackgroundAbsoluteRect.height), size: textInput.backgroundView.bounds.size)
|
||||
textInput.contentView.frame = textInput.contentView.frame.offsetBy(dx: 0.0, dy: sourceAbsoluteRect.height - sourceBackgroundAbsoluteRect.height)
|
||||
@ -390,9 +392,9 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
self.itemNode.cancelInsertionAnimations()
|
||||
|
||||
let horizontalCurve = ChatMessageTransitionNode.horizontalAnimationCurve
|
||||
let horizontalCurve = ChatMessageTransitionNodeImpl.horizontalAnimationCurve
|
||||
let horizontalTransition: ContainedViewLayoutTransition = .animated(duration: horizontalDuration, curve: horizontalCurve)
|
||||
let verticalCurve = ChatMessageTransitionNode.verticalAnimationCurve
|
||||
let verticalCurve = ChatMessageTransitionNodeImpl.verticalAnimationCurve
|
||||
let verticalTransition: ContainedViewLayoutTransition = .animated(duration: verticalDuration, curve: verticalCurve)
|
||||
|
||||
let combinedTransition = CombinedTransition(horizontal: horizontalTransition, vertical: verticalTransition)
|
||||
@ -415,9 +417,27 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
|
||||
}
|
||||
} else if let itemNode = self.itemNode as? ChatMessageAnimatedStickerItemNode {
|
||||
itemNode.animateContentFromTextInputField(textInput: textInput, transition: combinedTransition)
|
||||
itemNode.animateContentFromTextInputField(
|
||||
textInput: ChatMessageAnimatedStickerItemNode.AnimationTransitionTextInput(
|
||||
backgroundView: textInput.backgroundView,
|
||||
contentView: textInput.contentView,
|
||||
sourceRect: textInput.sourceRect,
|
||||
scrollOffset: textInput.scrollOffset
|
||||
),
|
||||
transition: combinedTransition
|
||||
)
|
||||
if let sourceReplyPanel = sourceReplyPanel {
|
||||
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
|
||||
itemNode.animateReplyPanel(
|
||||
sourceReplyPanel: ChatMessageAnimatedStickerItemNode.AnimationTransitionReplyPanel(
|
||||
titleNode: sourceReplyPanel.titleNode,
|
||||
textNode: sourceReplyPanel.textNode,
|
||||
lineNode: sourceReplyPanel.lineNode,
|
||||
imageNode: sourceReplyPanel.imageNode,
|
||||
relativeSourceRect: sourceReplyPanel.relativeSourceRect,
|
||||
relativeTargetRect: sourceReplyPanel.relativeTargetRect
|
||||
),
|
||||
transition: combinedTransition
|
||||
)
|
||||
}
|
||||
} else if let itemNode = self.itemNode as? ChatMessageStickerItemNode {
|
||||
itemNode.animateContentFromTextInputField(
|
||||
@ -479,15 +499,34 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
sourceReplyPanel = ReplyPanel(titleNode: replyPanel.titleNode, textNode: replyPanel.textNode, lineNode: replyPanel.lineNode, imageNode: replyPanel.imageNode, relativeSourceRect: replySourceAbsoluteFrame, relativeTargetRect: replySourceAbsoluteFrame.offsetBy(dx: 0.0, dy: replySourceAbsoluteFrame.height))
|
||||
}
|
||||
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
|
||||
if let itemNode = self.itemNode as? ChatMessageAnimatedStickerItemNode {
|
||||
itemNode.animateContentFromStickerGridItem(stickerSource: stickerSource, transition: combinedTransition)
|
||||
itemNode.animateContentFromStickerGridItem(
|
||||
stickerSource: ChatMessageAnimatedStickerItemNode.AnimationTransitionSticker(
|
||||
imageNode: stickerSource.imageNode,
|
||||
animationNode: stickerSource.animationNode,
|
||||
placeholderNode: stickerSource.placeholderNode,
|
||||
imageLayer: stickerSource.imageLayer,
|
||||
relativeSourceRect: stickerSource.relativeSourceRect
|
||||
),
|
||||
transition: combinedTransition
|
||||
)
|
||||
if let sourceAnimationNode = stickerSource.animationNode {
|
||||
itemNode.animationNode?.setFrameIndex(sourceAnimationNode.currentFrameIndex)
|
||||
}
|
||||
if let sourceReplyPanel = sourceReplyPanel {
|
||||
itemNode.animateReplyPanel(sourceReplyPanel: sourceReplyPanel, transition: combinedTransition)
|
||||
itemNode.animateReplyPanel(
|
||||
sourceReplyPanel: ChatMessageAnimatedStickerItemNode.AnimationTransitionReplyPanel(
|
||||
titleNode: sourceReplyPanel.titleNode,
|
||||
textNode: sourceReplyPanel.textNode,
|
||||
lineNode: sourceReplyPanel.lineNode,
|
||||
imageNode: sourceReplyPanel.imageNode,
|
||||
relativeSourceRect: sourceReplyPanel.relativeSourceRect,
|
||||
relativeTargetRect: sourceReplyPanel.relativeTargetRect
|
||||
),
|
||||
transition: combinedTransition
|
||||
)
|
||||
}
|
||||
} else if let itemNode = self.itemNode as? ChatMessageStickerItemNode {
|
||||
itemNode.animateContentFromStickerGridItem(
|
||||
@ -517,15 +556,15 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
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.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.endAnimation()
|
||||
})
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true)
|
||||
|
||||
switch stickerMediaInput {
|
||||
case .inputPanel, .universal:
|
||||
@ -544,7 +583,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
container.isHidden = true
|
||||
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
|
||||
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
|
||||
if let contextContainer = itemNode.animateFromMicInput(micInputNode: snapshotView, transition: combinedTransition) {
|
||||
@ -554,7 +593,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -contextContainer.contentRect.minX, dy: -contextContainer.contentRect.minY)
|
||||
contextContainer.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self, weak contextContainer, weak container] _ in
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self, weak contextContainer, weak container] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -569,13 +608,13 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
strongSelf.endAnimation()
|
||||
})
|
||||
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .videoMessage(videoMessage):
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
|
||||
if let itemNode = self.itemNode as? ChatMessageInstantVideoItemNode {
|
||||
itemNode.cancelInsertionAnimations()
|
||||
@ -591,9 +630,9 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
videoMessage.view.frame = videoMessage.view.frame.offsetBy(dx: targetAbsoluteRect.midX - sourceAbsoluteRect.midX, dy: targetAbsoluteRect.midY - sourceAbsoluteRect.midY)
|
||||
|
||||
self.containerNode.frame = targetAbsoluteRect.offsetBy(dx: -self.contextSourceNode.contentRect.minX, dy: -self.contextSourceNode.contentRect.minY)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, completion: { [weak self] _ in
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -618,7 +657,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
let sourceBackgroundAbsoluteRect = snapshotView.frame
|
||||
let sourceAbsoluteRect = CGRect(origin: CGPoint(x: sourceBackgroundAbsoluteRect.midX - self.contextSourceNode.contentRect.size.width / 2.0, y: sourceBackgroundAbsoluteRect.midY - self.contextSourceNode.contentRect.size.height / 2.0), size: self.contextSourceNode.contentRect.size)
|
||||
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
|
||||
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
|
||||
itemNode.animateContentFromMediaInput(snapshotView: snapshotView, transition: combinedTransition)
|
||||
@ -631,8 +670,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
|
||||
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -647,8 +686,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -669,7 +708,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
self.containerNode.addSubnode(self.contextSourceNode.contentNode)
|
||||
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNode.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
let combinedTransition = CombinedTransition(horizontal: .animated(duration: horizontalDuration, curve: ChatMessageTransitionNodeImpl.horizontalAnimationCurve), vertical: .animated(duration: verticalDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
|
||||
var targetContentRects: [CGRect] = []
|
||||
if let itemNode = self.itemNode as? ChatMessageBubbleItemNode {
|
||||
@ -709,8 +748,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
|
||||
self.contextSourceNode.updateAbsoluteRect?(self.containerNode.frame, UIScreen.main.bounds.size)
|
||||
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNode.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: sourceAbsoluteRect.midY - targetAbsoluteRect.midY), to: CGPoint(), duration: horizontalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.horizontalAnimationCurve.mediaTimingFunction, additive: true, force: true)
|
||||
self.containerNode.layer.animatePosition(from: CGPoint(x: sourceAbsoluteRect.midX - targetAbsoluteRect.midX, y: 0.0), to: CGPoint(), duration: verticalDuration, delay: delay, mediaTimingFunction: ChatMessageTransitionNodeImpl.verticalAnimationCurve.mediaTimingFunction, additive: true, force: true, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -736,8 +775,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
index += 1
|
||||
}
|
||||
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNode.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNode.verticalAnimationCurve, verticalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: sourceAbsoluteRect.minX - targetAbsoluteRect.minX, y: 0.0), ChatMessageTransitionNodeImpl.horizontalAnimationCurve, horizontalDuration)
|
||||
self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), ChatMessageTransitionNodeImpl.verticalAnimationCurve, verticalDuration)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -838,7 +877,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
private var currentPendingItems: [Int64: (Source, () -> Void)] = [:]
|
||||
|
||||
private var animatingItemNodes: [AnimatingItemNode] = []
|
||||
private var decorationItemNodes: [DecorationItemNode] = []
|
||||
private var decorationItemNodes: [DecorationItemNodeImpl] = []
|
||||
private var messageReactionContexts: [MessageReactionContext] = []
|
||||
|
||||
var hasScheduledTransitions: Bool {
|
||||
@ -891,8 +930,8 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
self.listNode.setCurrentSendAnimationCorrelationIds(correlationIds)
|
||||
}
|
||||
|
||||
func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode {
|
||||
let decorationItemNode = DecorationItemNode(itemNode: itemNode, contentView: decorationView, getContentAreaInScreenSpace: self.getContentAreaInScreenSpace)
|
||||
public func add(decorationView: UIView, itemNode: ChatMessageItemView) -> DecorationItemNode {
|
||||
let decorationItemNode = DecorationItemNodeImpl(itemNode: itemNode, contentView: decorationView, getContentAreaInScreenSpace: self.getContentAreaInScreenSpace)
|
||||
decorationItemNode.updateLayout(size: self.bounds.size)
|
||||
|
||||
self.decorationItemNodes.append(decorationItemNode)
|
||||
@ -907,10 +946,12 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
return decorationItemNode
|
||||
}
|
||||
|
||||
func remove(decorationNode: DecorationItemNode) {
|
||||
public func remove(decorationNode: DecorationItemNode) {
|
||||
self.decorationItemNodes.removeAll(where: { $0 === decorationNode })
|
||||
decorationNode.removeFromSupernode()
|
||||
decorationNode.overlayController?.dismiss()
|
||||
if let decorationNode = decorationNode as? DecorationItemNodeImpl {
|
||||
decorationNode.overlayController?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private func beginAnimation(itemNode: ChatMessageItemView, source: Source) {
|
||||
@ -961,7 +1002,7 @@ public final class ChatMessageTransitionNode: ASDisplayNode, ChatMessageTransiti
|
||||
animatingItemNode.frame = self.bounds
|
||||
animatingItemNode.beginAnimation()
|
||||
|
||||
self.onTransitionEvent(.animated(duration: ChatMessageTransitionNode.animationDuration, curve: ChatMessageTransitionNode.verticalAnimationCurve))
|
||||
self.onTransitionEvent(.animated(duration: ChatMessageTransitionNodeImpl.animationDuration, curve: ChatMessageTransitionNodeImpl.verticalAnimationCurve))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4219,7 +4219,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeSnapshotForTransition() -> ChatMessageTransitionNode.Source.TextInput? {
|
||||
func makeSnapshotForTransition() -> ChatMessageTransitionNodeImpl.Source.TextInput? {
|
||||
guard let backgroundImage = self.transparentTextInputBackgroundImage else {
|
||||
return nil
|
||||
}
|
||||
@ -4242,7 +4242,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
|
||||
contentView.frame = textInputNode.frame
|
||||
|
||||
return ChatMessageTransitionNode.Source.TextInput(
|
||||
return ChatMessageTransitionNodeImpl.Source.TextInput(
|
||||
backgroundView: backgroundView,
|
||||
contentView: contentView,
|
||||
sourceRect: self.view.convert(self.bounds, to: nil),
|
||||
|
@ -8,6 +8,7 @@ import StickerResources
|
||||
import Emoji
|
||||
import UniversalMediaPlayer
|
||||
import ChatMessageInteractiveMediaNode
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
|
||||
private final class PrefetchMediaContext {
|
||||
let fetchDisposable = MetaDisposable()
|
||||
|
@ -8,7 +8,7 @@ import AccountContext
|
||||
import ChatControllerInteraction
|
||||
import ChatHistoryEntry
|
||||
|
||||
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNode?, allUpdated: Bool) -> ChatHistoryViewTransition {
|
||||
func preparedChatHistoryViewTransition(from fromView: ChatHistoryView?, to toView: ChatHistoryView, reason: ChatHistoryViewTransitionReason, reverse: Bool, chatLocation: ChatLocation, controllerInteraction: ChatControllerInteraction, scrollPosition: ChatHistoryViewScrollPosition?, scrollAnimationCurve: ListViewAnimationCurve?, initialData: InitialMessageHistoryData?, keyboardButtonsMessage: Message?, cachedData: CachedPeerData?, cachedDataMessages: [MessageId: Message]?, readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData]?, flashIndicators: Bool, updatedMessageSelection: Bool, messageTransitionNode: ChatMessageTransitionNodeImpl?, allUpdated: Bool) -> ChatHistoryViewTransition {
|
||||
var mergeResult: (deleteIndices: [Int], indicesAndItems: [(Int, ChatHistoryEntry, Int?)], updateIndices: [(Int, ChatHistoryEntry, Int)])
|
||||
let allUpdated = allUpdated || (fromView?.associatedData != toView.associatedData)
|
||||
if reverse {
|
||||
|
@ -1,3 +0,0 @@
|
||||
module TelegramUIPrivate {
|
||||
export *
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user