From d367d668997b054d0c3dace7f5f3d8dca07b886d Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 15 Oct 2023 15:56:50 +0400 Subject: [PATCH] Refactoring --- submodules/TelegramUI/BUILD | 1 + .../Chat/ChatMessageBubbleItemNode/BUILD | 86 +++++++++++ .../Sources/ChatMessageBubbleItemNode.swift | 142 +++++++++++------- .../Chat/ChatMessageActionOptions.swift | 1 + .../TelegramUI/Sources/ChatController.swift | 1 + .../ChatInterfaceStateContextMenus.swift | 1 + .../TelegramUI/Sources/ChatLoadingNode.swift | 1 + .../Sources/ChatMessageItemImpl.swift | 1 + .../Sources/ChatMessageTransitionNode.swift | 23 ++- 9 files changed, 200 insertions(+), 57 deletions(-) create mode 100644 submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD rename submodules/TelegramUI/{ => Components/Chat/ChatMessageBubbleItemNode}/Sources/ChatMessageBubbleItemNode.swift (97%) diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index 7a4e130301..7f38a8733b 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -403,6 +403,7 @@ swift_library( "//submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode", "//submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode", "//submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode", ] + select({ "@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets, "//build-system:ios_sim_arm64": [], diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD new file mode 100644 index 0000000000..5b8b444a8d --- /dev/null +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/BUILD @@ -0,0 +1,86 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatMessageBubbleItemNode", + module_name = "ChatMessageBubbleItemNode", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit", + "//submodules/Display", + "//submodules/SSignalKit/SwiftSignalKit", + "//submodules/Postbox", + "//submodules/TelegramCore", + "//submodules/TelegramPresentationData", + "//submodules/TelegramUIPreferences", + "//submodules/TextFormat", + "//submodules/AccountContext", + "//submodules/TemporaryCachedPeerDataManager", + "//submodules/LocalizedPeerData", + "//submodules/ContextUI", + "//submodules/TelegramUniversalVideoContent", + "//submodules/MosaicLayout", + "//submodules/TextSelectionNode", + "//submodules/PlatformRestrictionMatching", + "//submodules/Emoji", + "//submodules/PersistentStringHash", + "//submodules/GridMessageSelectionNode", + "//submodules/AppBundle", + "//submodules/Markdown", + "//submodules/WallpaperBackgroundNode", + "//submodules/ChatPresentationInterfaceState", + "//submodules/ChatMessageBackground", + "//submodules/TelegramUI/Components/AnimationCache", + "//submodules/TelegramUI/Components/MultiAnimationRenderer", + "//submodules/ComponentFlow", + "//submodules/TelegramUI/Components/EmojiStatusComponent", + "//submodules/TelegramUI/Components/ChatControllerInteraction", + "//submodules/TelegramUI/Components/Chat/ChatMessageForwardInfoNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageDateAndStatusNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatHistoryEntry", + "//submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon", + "//submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageCallBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageInteractiveFileNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageFileBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageWebpageBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode", + "//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/ChatMessageInstantVideoBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageCommentFooterContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageContactBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousDescriptionContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousLinkContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageEventLogPreviousMessageContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageGameBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageInvoiceBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageMapBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageMediaBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageProfilePhotoSuggestionContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageRestrictedBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageStoryMentionContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageUnsupportedBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode", + "//submodules/TelegramUI/Components/Chat/ChatMessageGiveawayBubbleContentNode", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift similarity index 97% rename from submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift rename to submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 87ebf8e699..f5b01f97fc 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -371,18 +371,18 @@ private func mapVisibility(_ visibility: ListViewItemNodeVisibility, boundsSize: } } -class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode { - class ContentContainer { - let contentMessageStableId: UInt32 - let sourceNode: ContextExtractedContentContainingNode - let containerNode: ContextControllerSourceNode - var backgroundWallpaperNode: ChatMessageBubbleBackdrop? - var backgroundNode: ChatMessageBackground? - var selectionBackgroundNode: ASDisplayNode? +public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode { + public class ContentContainer { + public let contentMessageStableId: UInt32 + public let sourceNode: ContextExtractedContentContainingNode + public let containerNode: ContextControllerSourceNode + public var backgroundWallpaperNode: ChatMessageBubbleBackdrop? + public var backgroundNode: ChatMessageBackground? + public var selectionBackgroundNode: ASDisplayNode? private var currentParams: (size: CGSize, contentOrigin: CGPoint, presentationData: ChatPresentationData, graphics: PrincipalThemeEssentialGraphics, backgroundType: ChatMessageBackgroundType, presentationContext: ChatPresentationContext, mediaBox: MediaBox, messageSelection: Bool?, selectionInsets: UIEdgeInsets)? - init(contentMessageStableId: UInt32) { + public init(contentMessageStableId: UInt32) { self.contentMessageStableId = contentMessageStableId self.sourceNode = ContextExtractedContentContainingNode() @@ -519,14 +519,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - let mainContextSourceNode: ContextExtractedContentContainingNode + public let mainContextSourceNode: ContextExtractedContentContainingNode private let mainContainerNode: ContextControllerSourceNode private let backgroundWallpaperNode: ChatMessageBubbleBackdrop private let backgroundNode: ChatMessageBackground private let shadowNode: ChatMessageShadowNode private var clippingNode: ChatMessageBubbleClippingNode - override var extractedBackgroundNode: ASDisplayNode? { + override public var extractedBackgroundNode: ASDisplayNode? { return self.shadowNode } @@ -540,7 +540,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode private var credibilityIconView: ComponentHostView? private var credibilityIconComponent: EmojiStatusComponent? private var forwardInfoNode: ChatMessageForwardInfoNode? - var forwardInfoReferenceNode: ASDisplayNode? { + public var forwardInfoReferenceNode: ASDisplayNode? { return self.forwardInfoNode } @@ -549,7 +549,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode private var contentContainersWrapperNode: ASDisplayNode private var contentContainers: [ContentContainer] = [] - private(set) var contentNodes: [ChatMessageBubbleContentNode] = [] + public private(set) var contentNodes: [ChatMessageBubbleContentNode] = [] private var mosaicStatusNode: ChatMessageDateAndStatusNode? private var actionButtonsNode: ChatMessageActionButtonsNode? private var reactionButtonsNode: ChatMessageReactionButtonsNode? @@ -576,7 +576,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode //private let debugNode: ASDisplayNode - override var visibility: ListViewItemNodeVisibility { + override public var visibility: ListViewItemNodeVisibility { didSet { if self.visibility != oldValue { for contentNode in self.contentNodes { @@ -611,7 +611,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - required init() { + required public init() { self.mainContextSourceNode = ContextExtractedContentContainingNode() self.mainContainerNode = ContextControllerSourceNode() self.backgroundWallpaperNode = ChatMessageBubbleBackdrop() @@ -759,11 +759,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - required init?(coder aDecoder: NSCoder) { + required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - override func cancelInsertionAnimations() { + override public func cancelInsertionAnimations() { self.shadowNode.layer.removeAllAnimations() func process(node: ASDisplayNode) { @@ -797,7 +797,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode process(node: self) } - 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.shadowNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) @@ -832,7 +832,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode process(node: self) } - override func animateRemoved(_ currentTimestamp: Double, duration: Double) { + override public func animateRemoved(_ currentTimestamp: Double, duration: Double) { super.animateRemoved(currentTimestamp, duration: duration) self.allowsGroupOpacity = true @@ -844,7 +844,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: self.bounds.width / 2.0 - self.backgroundNode.frame.midX, y: self.backgroundNode.frame.midY), duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true) } - override func animateAdded(_ currentTimestamp: Double, duration: Double) { + override public func animateAdded(_ currentTimestamp: Double, duration: Double) { super.animateAdded(currentTimestamp, duration: duration) if let subnodes = self.subnodes { @@ -858,7 +858,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) { + public func animateFromLoadingPlaceholder(delay: Double, transition: ContainedViewLayoutTransition) { guard let item = self.item else { return } @@ -867,8 +867,22 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode transition.animatePositionAdditive(node: self, offset: CGPoint(x: incoming ? 30.0 : -30.0, y: -30.0), delay: delay) transition.animateTransformScale(node: self, from: CGPoint(x: 0.85, y: 0.85), delay: delay) } + + public final class AnimationTransitionTextInput { + let backgroundView: UIView + let contentView: UIView + let sourceRect: CGRect + let scrollOffset: CGFloat - func animateContentFromTextInputField(textInput: ChatMessageTransitionNodeImpl.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) { let widthDifference = self.backgroundNode.frame.width - textInput.backgroundView.frame.width let heightDifference = self.backgroundNode.frame.height - textInput.backgroundView.frame.height @@ -900,8 +914,26 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } } + + 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: ChatMessageTransitionNodeImpl.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.mainContextSourceNode.contentNode.view.convert(sourceReplyPanel.relativeSourceRect, to: replyInfoNode.view) let mappedPanel = ChatMessageReplyInfoNode.TransitionReplyPanel( @@ -916,7 +948,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - func animateFromMicInput(micInputNode: UIView, transition: CombinedTransition) -> ContextExtractedContentContainingNode? { + public func animateFromMicInput(micInputNode: UIView, transition: CombinedTransition) -> ContextExtractedContentContainingNode? { for contentNode in self.contentNodes { if let contentNode = contentNode as? ChatMessageFileBubbleContentNode { let statusContainerNode = contentNode.interactiveFileNode.statusContainerNode @@ -939,11 +971,11 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - func animateContentFromMediaInput(snapshotView: UIView, transition: CombinedTransition) { + public func animateContentFromMediaInput(snapshotView: UIView, transition: CombinedTransition) { self.mainContextSourceNode.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) } - func animateContentFromGroupedMediaInput(transition: CombinedTransition) -> [CGRect] { + public func animateContentFromGroupedMediaInput(transition: CombinedTransition) -> [CGRect] { self.mainContextSourceNode.contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1) var rects: [CGRect] = [] @@ -955,7 +987,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return rects } - override func didLoad() { + override public func didLoad() { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) @@ -1140,7 +1172,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - 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 currentContentClassesPropertiesAndLayouts: [(Message, AnyClass, Bool, (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))))] = [] for contentNode in self.contentNodes { if let message = contentNode.item?.message { @@ -3580,7 +3612,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) { + override public func updateAccessibilityData(_ accessibilityData: ChatMessageAccessibilityData) { super.updateAccessibilityData(accessibilityData) self.messageAccessibilityArea.accessibilityLabel = accessibilityData.label @@ -3620,7 +3652,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func shouldAnimateHorizontalFrameTransition() -> Bool { + override public func shouldAnimateHorizontalFrameTransition() -> Bool { return false /*if let _ = self.backgroundFrameTransition { return true @@ -3629,7 +3661,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode }*/ } - override func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) { + override public func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) { super.animateFrameTransition(progress, currentValue) /*if let backgroundFrameTransition = self.backgroundFrameTransition { @@ -3674,7 +3706,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode }*/ } - @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + @objc private func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation, let item = self.item { @@ -4117,7 +4149,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if !self.bounds.contains(point) { return nil } @@ -4167,7 +4199,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return super.hitTest(point, with: event) } - override func transitionNode(id: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { + override public func transitionNode(id: MessageId, media: Media, adjustRect: Bool) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? { for contentNode in self.contentNodes { if let result = contentNode.transitionNode(messageId: id, media: media, adjustRect: adjustRect) { if self.contentNodes.count == 1 && self.contentNodes.first is ChatMessageMediaBubbleContentNode && self.nameNode == nil && self.adminBadgeNode == nil && self.forwardInfoNode == nil && self.replyInfoNode == nil { @@ -4209,7 +4241,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func updateHiddenMedia() { + override public func updateHiddenMedia() { var hasHiddenMosaicStatus = false var hasHiddenBackground = false if let item = self.item { @@ -4242,7 +4274,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode self.backgroundWallpaperNode.isHidden = hasHiddenBackground } - override func updateAutomaticMediaDownloadSettings() { + override public func updateAutomaticMediaDownloadSettings() { if let item = self.item { for contentNode in self.contentNodes { contentNode.updateAutomaticMediaDownloadSettings(item.controllerInteraction.automaticMediaDownloadSettings) @@ -4250,7 +4282,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? { + override public func playMediaWithSound() -> ((Double?) -> Void, Bool, Bool, Bool, ASDisplayNode?)? { for contentNode in self.contentNodes { if let playMediaWithSound = contentNode.playMediaWithSound() { return playMediaWithSound @@ -4259,7 +4291,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func updateSelectionState(animated: Bool) { + override public func updateSelectionState(animated: Bool) { guard let item = self.item else { return } @@ -4372,13 +4404,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func updateSearchTextHighlightState() { + override public func updateSearchTextHighlightState() { for contentNode in self.contentNodes { contentNode.updateSearchTextHighlightState(text: self.item?.controllerInteraction.searchTextHighightState?.0, messages: self.item?.controllerInteraction.searchTextHighightState?.1) } } - override func updateHighlightedState(animated: Bool) { + override public func updateHighlightedState(animated: Bool) { super.updateHighlightedState(animated: animated) guard let item = self.item, let _ = self.backgroundType else { @@ -4411,7 +4443,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - @objc func shareButtonPressed() { + @objc private func shareButtonPressed() { if let item = self.item { if case .pinnedMessages = item.associatedData.subject { item.controllerInteraction.navigateToMessageStandalone(item.content.firstMessage.id) @@ -4439,7 +4471,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } 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 @@ -4570,7 +4602,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode 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) guard !self.mainContextSourceNode.isExtractedToContextPreview else { return @@ -4621,7 +4653,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { + override public func applyAbsoluteOffset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) { if !self.mainContextSourceNode.isExtractedToContextPreview { self.applyAbsoluteOffsetInternal(value: CGPoint(x: -value.x, y: -value.y), animationCurve: animationCurve, duration: duration) } @@ -4651,7 +4683,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? { + override public func getMessageContextSourceNode(stableId: UInt32?) -> ContextExtractedContentContainingNode? { if self.contentContainers.count > 1 { return self.contentContainers.first(where: { $0.contentMessageStableId == stableId })?.sourceNode ?? self.mainContextSourceNode } else { @@ -4659,7 +4691,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) { + override public func addAccessoryItemNode(_ accessoryItemNode: ListViewAccessoryItemNode) { self.mainContextSourceNode.contentNode.addSubnode(accessoryItemNode) } @@ -4669,7 +4701,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return self.mainContextSourceNode.isExtractedToContextPreview || hasWallpaper || isPreview || !self.disablesComments } - override func openMessageContextMenu() { + override public func openMessageContextMenu() { guard let item = self.item else { return } @@ -4677,7 +4709,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode item.controllerInteraction.openMessageContextMenu(item.message, true, self, subFrame, 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 } @@ -4692,7 +4724,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func targetForStoryTransition(id: StoryId) -> UIView? { + override public func targetForStoryTransition(id: StoryId) -> UIView? { guard let item = self.item else { return nil } @@ -4713,13 +4745,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - override func unreadMessageRangeUpdated() { + override public func unreadMessageRangeUpdated() { for contentNode in self.contentNodes { contentNode.unreadMessageRangeUpdated() } } - func animateQuizInvalidOptionSelected() { + public func animateQuizInvalidOptionSelected() { if let supernode = self.supernode, let subnodes = supernode.subnodes { for i in 0 ..< subnodes.count { if subnodes[i] === self { @@ -4776,7 +4808,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode self.layer.add(animation, forKey: "quizInvalidRotation") } - func updatePsaTooltipMessageState(animated: Bool) { + public func updatePsaTooltipMessageState(animated: Bool) { guard let item = self.item else { return } @@ -4785,7 +4817,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } } - override func getStatusNode() -> ASDisplayNode? { + override public func getStatusNode() -> ASDisplayNode? { for contentNode in self.contentNodes { if let statusNode = contentNode.getStatusNode() { return statusNode @@ -4797,7 +4829,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return nil } - func hasExpandedAudioTranscription() -> Bool { + public func hasExpandedAudioTranscription() -> Bool { for contentNode in self.contentNodes { if let contentNode = contentNode as? ChatMessageFileBubbleContentNode { return contentNode.interactiveFileNode.hasExpandedAudioTranscription @@ -4808,7 +4840,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode return false } - override func contentFrame() -> CGRect { + override public func contentFrame() -> CGRect { return self.backgroundNode.frame } } diff --git a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift index 917900adaf..cbf55e6255 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatMessageActionOptions.swift @@ -14,6 +14,7 @@ import PresentationDataUtils import ChatMessageTextBubbleContentNode import TextFormat import ChatMessageItemView +import ChatMessageBubbleItemNode private enum OptionsId: Hashable { case reply diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index b69aa0cd33..68b054a33a 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -111,6 +111,7 @@ import ChatMessageItem import ChatMessageItemView import ChatMessageItemCommon import ChatMessageAnimatedStickerItemNode +import ChatMessageBubbleItemNode public enum ChatControllerPeekActions { case standard diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index 374ceedf7f..7b6c105f08 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -35,6 +35,7 @@ import TextNodeWithEntities import ChatControllerInteraction import ChatMessageItemCommon import ChatMessageItemView +import ChatMessageBubbleItemNode private struct MessageContextMenuData { let starStatus: Bool? diff --git a/submodules/TelegramUI/Sources/ChatLoadingNode.swift b/submodules/TelegramUI/Sources/ChatLoadingNode.swift index 20374f5cd7..2573b20227 100644 --- a/submodules/TelegramUI/Sources/ChatLoadingNode.swift +++ b/submodules/TelegramUI/Sources/ChatLoadingNode.swift @@ -15,6 +15,7 @@ import ChatMessageItemView import ChatMessageStickerItemNode import ChatMessageInstantVideoItemNode import ChatMessageAnimatedStickerItemNode +import ChatMessageBubbleItemNode final class ChatLoadingNode: ASDisplayNode { private let backgroundNode: NavigationBackgroundNode diff --git a/submodules/TelegramUI/Sources/ChatMessageItemImpl.swift b/submodules/TelegramUI/Sources/ChatMessageItemImpl.swift index b90b25b23b..75d7ebdeba 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemImpl.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemImpl.swift @@ -16,6 +16,7 @@ import ChatMessageItem import ChatMessageItemView import ChatMessageStickerItemNode import ChatMessageAnimatedStickerItemNode +import ChatMessageBubbleItemNode private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge { if let story = media as? TelegramMediaStory, story.isMention { diff --git a/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift b/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift index e3703a51da..d2ebffd67e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTransitionNode.swift @@ -18,6 +18,7 @@ import ChatMessageStickerItemNode import ChatMessageInstantVideoItemNode import ChatMessageAnimatedStickerItemNode import ChatMessageTransitionNode +import ChatMessageBubbleItemNode private func convertAnimatingSourceRect(_ rect: CGRect, fromView: UIView, toView: UIView?) -> CGRect { if let presentationLayer = fromView.layer.presentation() { @@ -412,9 +413,27 @@ public final class ChatMessageTransitionNodeImpl: ASDisplayNode, ChatMessageTran self.contextSourceNode.applyAbsoluteOffset?(CGPoint(x: 0.0, y: sourceAbsoluteRect.maxY - targetAbsoluteRect.maxY), verticalCurve, verticalDuration) if let itemNode = self.itemNode as? ChatMessageBubbleItemNode { - itemNode.animateContentFromTextInputField(textInput: textInput, transition: combinedTransition) + itemNode.animateContentFromTextInputField( + textInput: ChatMessageBubbleItemNode.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: ChatMessageBubbleItemNode.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? ChatMessageAnimatedStickerItemNode { itemNode.animateContentFromTextInputField(