mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Reaction animation updates
This commit is contained in:
@@ -174,6 +174,13 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
}
|
||||
|
||||
let firstMessage = item.content.firstMessage
|
||||
|
||||
if let reactionsAttribute = mergedMessageReactions(attributes: firstMessage.attributes), !reactionsAttribute.reactions.isEmpty {
|
||||
if result.last?.1 == ChatMessageWebpageBubbleContentNode.self || result.last?.1 == ChatMessagePollBubbleContentNode.self || result.last?.1 == ChatMessageContactBubbleContentNode.self {
|
||||
result.append((firstMessage, ChatMessageReactionsFooterContentNode.self, ChatMessageEntryAttributes(), BubbleItemAttributes(isAttachment: true, neighborType: .freeform, neighborSpacing: .default)))
|
||||
}
|
||||
}
|
||||
|
||||
if !isAction && !Namespaces.Message.allScheduled.contains(firstMessage.id.namespace) {
|
||||
var hasDiscussion = false
|
||||
if let channel = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel, case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
|
||||
@@ -920,7 +927,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
forwardInfoLayout: (ChatPresentationData, PresentationStrings, ChatMessageForwardInfoType, Peer?, String?, String?, CGSize) -> (CGSize, (CGFloat) -> ChatMessageForwardInfoNode),
|
||||
replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContext, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode),
|
||||
actionButtonsLayout: (AccountContext, ChatPresentationThemeData, PresentationChatBubbleCorners, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)),
|
||||
mosaicStatusLayout: (ChatMessageDateAndStatusNode.Arguments) -> (CGFloat, (CGFloat) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode)),
|
||||
mosaicStatusLayout: (ChatMessageDateAndStatusNode.Arguments) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation) -> ChatMessageDateAndStatusNode)),
|
||||
layoutConstants: ChatMessageItemLayoutConstants,
|
||||
currentItem: ChatMessageItem?,
|
||||
currentForwardInfo: (Peer?, String?)?,
|
||||
@@ -1330,7 +1337,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
prepareContentPosition = .linear(top: topPosition, bottom: refinedBottomPosition)
|
||||
}
|
||||
|
||||
let contentItem = ChatMessageBubbleContentItem(context: item.context, controllerInteraction: item.controllerInteraction, message: message, read: read, chatLocation: item.chatLocation, presentationData: item.presentationData, associatedData: item.associatedData, attributes: attributes, isItemPinned: isItemPinned, isItemEdited: isItemEdited)
|
||||
let contentItem = ChatMessageBubbleContentItem(context: item.context, controllerInteraction: item.controllerInteraction, message: message, topMessage: item.content.firstMessage, read: read, chatLocation: item.chatLocation, presentationData: item.presentationData, associatedData: item.associatedData, attributes: attributes, isItemPinned: isItemPinned, isItemEdited: isItemEdited)
|
||||
|
||||
var itemSelection: Bool?
|
||||
switch content {
|
||||
@@ -1457,7 +1464,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
let lastNodeTopPosition: ChatMessageBubbleRelativePosition = .None(bottomNodeMergeStatus)
|
||||
|
||||
var calculatedGroupFramesAndSize: ([(CGRect, MosaicItemPosition)], CGSize)?
|
||||
var mosaicStatusSizeAndApply: (CGSize, (Bool) -> ChatMessageDateAndStatusNode)?
|
||||
var mosaicStatusSizeAndApply: (CGSize, (ListViewItemUpdateAnimation) -> ChatMessageDateAndStatusNode)?
|
||||
|
||||
if let mosaicRange = mosaicRange {
|
||||
let maxSize = layoutConstants.image.maxDimensions.fittedToWidthOrSmaller(maximumContentWidth - layoutConstants.image.bubbleInsets.left - layoutConstants.image.bubbleInsets.right)
|
||||
@@ -2107,7 +2114,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
contentNodeFramesPropertiesAndApply: [(CGRect, ChatMessageBubbleContentProperties, Bool, (ListViewItemUpdateAnimation, Bool) -> Void)],
|
||||
contentContainerNodeFrames: [(UInt32, CGRect, Bool?, CGFloat)],
|
||||
mosaicStatusOrigin: CGPoint?,
|
||||
mosaicStatusSizeAndApply: (CGSize, (Bool) -> ChatMessageDateAndStatusNode)?,
|
||||
mosaicStatusSizeAndApply: (CGSize, (ListViewItemUpdateAnimation) -> ChatMessageDateAndStatusNode)?,
|
||||
needsShareButton: Bool
|
||||
) -> Void {
|
||||
guard let strongSelf = selfReference.value else {
|
||||
@@ -2123,10 +2130,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
strongSelf.appliedForwardInfo = (forwardSource, forwardAuthorSignature)
|
||||
strongSelf.updateAccessibilityData(accessibilityData)
|
||||
|
||||
var transition: ContainedViewLayoutTransition = .immediate
|
||||
var legacyTransition: ContainedViewLayoutTransition = .immediate
|
||||
var useDisplayLinkAnimations = false
|
||||
if case let .System(duration) = animation {
|
||||
transition = .animated(duration: duration, curve: .spring)
|
||||
if case let .System(duration, _) = animation {
|
||||
legacyTransition = .animated(duration: duration, curve: .spring)
|
||||
|
||||
if let subject = item.associatedData.subject, case .forwardedMessages = subject {
|
||||
useDisplayLinkAnimations = true
|
||||
@@ -2150,9 +2157,9 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
let hasWallpaper = item.presentationData.theme.wallpaper.hasWallpaper
|
||||
if item.presentationData.theme.theme.forceSync {
|
||||
transition = .immediate
|
||||
legacyTransition = .immediate
|
||||
}
|
||||
strongSelf.backgroundNode.setType(type: backgroundType, highlighted: strongSelf.highlightedState, graphics: graphics, maskMode: strongSelf.backgroundMaskMode, hasWallpaper: hasWallpaper, transition: transition, backgroundNode: presentationContext.backgroundNode)
|
||||
strongSelf.backgroundNode.setType(type: backgroundType, highlighted: strongSelf.highlightedState, graphics: graphics, maskMode: strongSelf.backgroundMaskMode, hasWallpaper: hasWallpaper, transition: legacyTransition, backgroundNode: presentationContext.backgroundNode)
|
||||
strongSelf.backgroundWallpaperNode.setType(type: backgroundType, theme: item.presentationData.theme, essentialGraphics: graphics, maskMode: strongSelf.backgroundMaskMode, backgroundNode: presentationContext.backgroundNode)
|
||||
strongSelf.shadowNode.setType(type: backgroundType, hasWallpaper: hasWallpaper, graphics: graphics)
|
||||
|
||||
@@ -2178,14 +2185,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
let deliveryFailedFrame = CGRect(origin: CGPoint(x: backgroundFrame.maxX + deliveryFailedInset - deliveryFailedSize.width, y: backgroundFrame.maxY - deliveryFailedSize.height), size: deliveryFailedSize)
|
||||
if isAppearing {
|
||||
deliveryFailedNode.frame = deliveryFailedFrame
|
||||
transition.animatePositionAdditive(node: deliveryFailedNode, offset: CGPoint(x: deliveryFailedInset, y: 0.0))
|
||||
legacyTransition.animatePositionAdditive(node: deliveryFailedNode, offset: CGPoint(x: deliveryFailedInset, y: 0.0))
|
||||
} else {
|
||||
transition.updateFrame(node: deliveryFailedNode, frame: deliveryFailedFrame)
|
||||
animation.animator.updateFrame(layer: deliveryFailedNode.layer, frame: deliveryFailedFrame, completion: nil)
|
||||
}
|
||||
} else if let deliveryFailedNode = strongSelf.deliveryFailedNode {
|
||||
strongSelf.deliveryFailedNode = nil
|
||||
transition.updateAlpha(node: deliveryFailedNode, alpha: 0.0)
|
||||
transition.updateFrame(node: deliveryFailedNode, frame: deliveryFailedNode.frame.offsetBy(dx: 24.0, dy: 0.0), completion: { [weak deliveryFailedNode] _ in
|
||||
animation.animator.updateAlpha(layer: deliveryFailedNode.layer, alpha: 0.0, completion: nil)
|
||||
animation.animator.updateFrame(layer: deliveryFailedNode.layer, frame: deliveryFailedNode.frame.offsetBy(dx: 24.0, dy: 0.0), completion: { [weak deliveryFailedNode] _ in
|
||||
deliveryFailedNode?.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
@@ -2194,16 +2201,16 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
strongSelf.nameNode = nameNode
|
||||
nameNode.displaysAsynchronously = !item.presentationData.isPreview && !item.presentationData.theme.theme.forceSync
|
||||
|
||||
let previousNameNodeFrame = nameNode.frame
|
||||
//let previousNameNodeFrame = nameNode.frame
|
||||
let nameNodeFrame = CGRect(origin: CGPoint(x: contentOrigin.x + layoutConstants.text.bubbleInsets.left, y: layoutConstants.bubble.contentInsets.top + nameNodeOriginY), size: nameNodeSizeApply.0)
|
||||
nameNode.frame = nameNodeFrame
|
||||
if nameNode.supernode == nil {
|
||||
if !nameNode.isNodeLoaded {
|
||||
nameNode.isUserInteractionEnabled = false
|
||||
}
|
||||
strongSelf.clippingNode.addSubnode(nameNode)
|
||||
nameNode.frame = nameNodeFrame
|
||||
} else {
|
||||
transition.animatePositionAdditive(node: nameNode, offset: CGPoint(x: previousNameNodeFrame.maxX - nameNodeFrame.maxX, y: 0.0))
|
||||
animation.animator.updateFrame(layer: nameNode.layer, frame: nameNodeFrame, completion: nil)
|
||||
}
|
||||
|
||||
if let credibilityIconImage = currentCredibilityIconImage {
|
||||
@@ -2232,9 +2239,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
strongSelf.clippingNode.addSubnode(adminBadgeNode)
|
||||
adminBadgeNode.frame = adminBadgeFrame
|
||||
} else {
|
||||
let previousAdminBadgeFrame = adminBadgeNode.frame
|
||||
adminBadgeNode.frame = adminBadgeFrame
|
||||
transition.animatePositionAdditive(node: adminBadgeNode, offset: CGPoint(x: previousAdminBadgeFrame.maxX - adminBadgeFrame.maxX, y: 0.0))
|
||||
//let previousAdminBadgeFrame = adminBadgeNode.frame
|
||||
animation.animator.updateFrame(layer: adminBadgeNode.layer, frame: adminBadgeFrame, completion: nil)
|
||||
}
|
||||
} else {
|
||||
strongSelf.adminBadgeNode?.removeFromSupernode()
|
||||
@@ -2269,7 +2275,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
let previousForwardInfoNodeFrame = forwardInfoNode.frame
|
||||
let forwardInfoFrame = CGRect(origin: CGPoint(x: contentOrigin.x + layoutConstants.text.bubbleInsets.left, y: layoutConstants.bubble.contentInsets.top + forwardInfoOriginY), size: CGSize(width: bubbleContentWidth, height: forwardInfoSizeApply.0.height))
|
||||
if case let .System(duration) = animation {
|
||||
if case let .System(duration, _) = animation {
|
||||
if animateFrame {
|
||||
if useDisplayLinkAnimations {
|
||||
let animation = ListViewAnimation(from: previousForwardInfoNodeFrame, to: forwardInfoFrame, duration: duration * UIView.animationDurationFactor(), curve: strongSelf.preferredAnimationCurve, beginAt: beginAt, update: { _, frame in
|
||||
@@ -2309,7 +2315,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
let previousReplyInfoNodeFrame = replyInfoNode.frame
|
||||
replyInfoNode.frame = CGRect(origin: CGPoint(x: contentOrigin.x + layoutConstants.text.bubbleInsets.left, y: layoutConstants.bubble.contentInsets.top + replyInfoOriginY), size: replyInfoSizeApply.0)
|
||||
if case let .System(duration) = animation {
|
||||
if case let .System(duration, _) = animation {
|
||||
if animateFrame {
|
||||
replyInfoNode.layer.animateFrame(from: previousReplyInfoNodeFrame, to: replyInfoNode.frame, duration: duration, timingFunction: timingFunction)
|
||||
}
|
||||
@@ -2561,7 +2567,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
let contentNodeFrame = relativeFrame.offsetBy(dx: contentOrigin.x, dy: useContentOrigin ? contentOrigin.y : 0.0)
|
||||
let previousContentNodeFrame = contentNode.frame
|
||||
|
||||
if case let .System(duration) = animation {
|
||||
if case let .System(duration, _) = animation {
|
||||
var animateFrame = false
|
||||
var animateAlpha = false
|
||||
if let addedContentNodes = addedContentNodes {
|
||||
@@ -2581,8 +2587,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
})
|
||||
strongSelf.setAnimationForKey("contentNode\(contentNodeIndex)Frame", animation: animation)
|
||||
} else {
|
||||
contentNode.frame = contentNodeFrame
|
||||
contentNode.layer.animateFrame(from: previousContentNodeFrame, to: contentNodeFrame, duration: duration, timingFunction: timingFunction)
|
||||
animation.animator.updateFrame(layer: contentNode.layer, frame: contentNodeFrame, completion: nil)
|
||||
}
|
||||
} else if animateAlpha {
|
||||
contentNode.frame = contentNodeFrame
|
||||
@@ -2600,7 +2605,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
|
||||
if let mosaicStatusOrigin = mosaicStatusOrigin, let (size, apply) = mosaicStatusSizeAndApply {
|
||||
let mosaicStatusNode = apply(transition.isAnimated)
|
||||
let mosaicStatusNode = apply(animation)
|
||||
if mosaicStatusNode !== strongSelf.mosaicStatusNode {
|
||||
strongSelf.mosaicStatusNode?.removeFromSupernode()
|
||||
strongSelf.mosaicStatusNode = mosaicStatusNode
|
||||
@@ -2627,18 +2632,53 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
|
||||
if case .System = animation, !strongSelf.mainContextSourceNode.isExtractedToContextPreview {
|
||||
if !strongSelf.backgroundNode.frame.equalTo(backgroundFrame) {
|
||||
strongSelf.backgroundFrameTransition = (strongSelf.backgroundNode.frame, backgroundFrame)
|
||||
/*strongSelf.backgroundFrameTransition = (strongSelf.backgroundNode.frame, backgroundFrame)
|
||||
if let type = strongSelf.backgroundNode.type {
|
||||
if case .none = type {
|
||||
} else {
|
||||
strongSelf.clippingNode.clipsToBounds = true
|
||||
}
|
||||
}*/
|
||||
|
||||
animation.animator.updateFrame(layer: strongSelf.backgroundNode.layer, frame: backgroundFrame, completion: nil)
|
||||
animation.animator.updatePosition(layer: strongSelf.clippingNode.layer, position: backgroundFrame.center, completion: nil)
|
||||
strongSelf.clippingNode.clipsToBounds = true
|
||||
animation.animator.updateBounds(layer: strongSelf.clippingNode.layer, bounds: CGRect(origin: CGPoint(x: backgroundFrame.minX, y: backgroundFrame.minY), size: backgroundFrame.size), completion: { [weak strongSelf] _ in
|
||||
let _ = strongSelf
|
||||
//strongSelf?.clippingNode.clipsToBounds = false
|
||||
})
|
||||
|
||||
strongSelf.backgroundNode.updateLayout(size: backgroundFrame.size, transition: animation)
|
||||
animation.animator.updateFrame(layer: strongSelf.backgroundWallpaperNode.layer, frame: backgroundFrame, completion: nil)
|
||||
strongSelf.shadowNode.updateLayout(backgroundFrame: backgroundFrame, transition: animation.transition)
|
||||
|
||||
if let type = strongSelf.backgroundNode.type {
|
||||
var incomingOffset: CGFloat = 0.0
|
||||
switch type {
|
||||
case .incoming:
|
||||
incomingOffset = 5.0
|
||||
default:
|
||||
break
|
||||
}
|
||||
strongSelf.mainContextSourceNode.contentRect = backgroundFrame.offsetBy(dx: incomingOffset, dy: 0.0)
|
||||
strongSelf.mainContainerNode.targetNodeForActivationProgressContentRect = strongSelf.mainContextSourceNode.contentRect
|
||||
if !strongSelf.mainContextSourceNode.isExtractedToContextPreview {
|
||||
if let (rect, size) = strongSelf.absoluteRect {
|
||||
strongSelf.updateAbsoluteRect(rect, within: size)
|
||||
}
|
||||
}
|
||||
}
|
||||
strongSelf.messageAccessibilityArea.frame = backgroundFrame
|
||||
|
||||
/*if let item = strongSelf.item, let shareButtonNode = strongSelf.shareButtonNode {
|
||||
let buttonSize = shareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: true)
|
||||
animation.animator.updateFrame(layer: shareButtonNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.maxX + 8.0, y: backgroundFrame.maxY - buttonSize.width - 1.0), size: buttonSize), completion: nil)
|
||||
}*/
|
||||
}
|
||||
if let shareButtonNode = strongSelf.shareButtonNode {
|
||||
let currentBackgroundFrame = strongSelf.backgroundNode.frame
|
||||
let buttonSize = shareButtonNode.update(presentationData: item.presentationData, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: true)
|
||||
shareButtonNode.frame = CGRect(origin: CGPoint(x: currentBackgroundFrame.maxX + 8.0, y: currentBackgroundFrame.maxY - buttonSize.width - 1.0), size: buttonSize)
|
||||
animation.animator.updateFrame(layer: shareButtonNode.layer, frame: CGRect(origin: CGPoint(x: currentBackgroundFrame.maxX + 8.0, y: currentBackgroundFrame.maxY - buttonSize.width - 1.0), size: buttonSize), completion: nil)
|
||||
}
|
||||
} else {
|
||||
if let _ = strongSelf.backgroundFrameTransition {
|
||||
@@ -2652,14 +2692,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
|
||||
if case .System = animation, strongSelf.mainContextSourceNode.isExtractedToContextPreview {
|
||||
transition.updateFrame(node: strongSelf.backgroundNode, frame: backgroundFrame)
|
||||
legacyTransition.updateFrame(node: strongSelf.backgroundNode, frame: backgroundFrame)
|
||||
|
||||
transition.updateFrame(node: strongSelf.clippingNode, frame: backgroundFrame)
|
||||
transition.updateBounds(node: strongSelf.clippingNode, bounds: CGRect(origin: CGPoint(x: backgroundFrame.minX, y: backgroundFrame.minY), size: backgroundFrame.size))
|
||||
legacyTransition.updateFrame(node: strongSelf.clippingNode, frame: backgroundFrame)
|
||||
legacyTransition.updateBounds(node: strongSelf.clippingNode, bounds: CGRect(origin: CGPoint(x: backgroundFrame.minX, y: backgroundFrame.minY), size: backgroundFrame.size))
|
||||
|
||||
strongSelf.backgroundNode.updateLayout(size: backgroundFrame.size, transition: transition)
|
||||
strongSelf.backgroundWallpaperNode.updateFrame(backgroundFrame, transition: transition)
|
||||
strongSelf.shadowNode.updateLayout(backgroundFrame: backgroundFrame, transition: transition)
|
||||
strongSelf.backgroundNode.updateLayout(size: backgroundFrame.size, transition: legacyTransition)
|
||||
strongSelf.backgroundWallpaperNode.updateFrame(backgroundFrame, transition: legacyTransition)
|
||||
strongSelf.shadowNode.updateLayout(backgroundFrame: backgroundFrame, transition: legacyTransition)
|
||||
} else {
|
||||
strongSelf.backgroundNode.frame = backgroundFrame
|
||||
strongSelf.clippingNode.frame = backgroundFrame
|
||||
@@ -2702,7 +2742,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
}
|
||||
strongSelf.insertSubnode(actionButtonsNode, belowSubnode: strongSelf.messageAccessibilityArea)
|
||||
} else {
|
||||
if case let .System(duration) = animation {
|
||||
if case let .System(duration, _) = animation {
|
||||
actionButtonsNode.layer.animateFrame(from: previousFrame, to: actionButtonsFrame, duration: duration, timingFunction: timingFunction)
|
||||
}
|
||||
}
|
||||
@@ -2780,7 +2820,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
override func animateFrameTransition(_ progress: CGFloat, _ currentValue: CGFloat) {
|
||||
super.animateFrameTransition(progress, currentValue)
|
||||
|
||||
if let backgroundFrameTransition = self.backgroundFrameTransition {
|
||||
/*if let backgroundFrameTransition = self.backgroundFrameTransition {
|
||||
let backgroundFrame = CGRect.interpolator()(backgroundFrameTransition.0, backgroundFrameTransition.1, progress) as! CGRect
|
||||
self.backgroundNode.frame = backgroundFrame
|
||||
|
||||
@@ -2819,7 +2859,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
|
||||
self.clippingNode.clipsToBounds = false
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
|
||||
|
||||
Reference in New Issue
Block a user