Reaction updates

This commit is contained in:
Ali
2022-01-25 21:15:28 +04:00
parent f47fa686e9
commit 85b5913b6a
17 changed files with 744 additions and 102 deletions

View File

@@ -1344,6 +1344,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
if strongSelf.canReadHistoryValue && !strongSelf.context.sharedContext.immediateExperimentalUISettings.skipReadHistory && !strongSelf.messageIdsWithReactionsScheduledForMarkAsSeen.isEmpty {
let messageIds = strongSelf.messageIdsWithReactionsScheduledForMarkAsSeen
let _ = strongSelf.displayUnseenReactionAnimations(messageIds: Array(messageIds))
strongSelf.messageIdsWithReactionsScheduledForMarkAsSeen.removeAll()
context?.account.viewTracker.updateMarkReactionsSeenForMessageIds(messageIds: messageIds)
}
@@ -2381,9 +2384,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let completion: (Bool, ListViewDisplayedItemRange) -> Void = { [weak self] wasTransformed, visibleRange in
if let strongSelf = self {
var newIncomingReactions: [MessageId: String] = [:]
var newIncomingReactions: [MessageId: (value: String, isLarge: Bool)] = [:]
if case .peer = strongSelf.chatLocation, let previousHistoryView = strongSelf.historyView {
var updatedIncomingReactions: [MessageId: String] = [:]
var updatedIncomingReactions: [MessageId: (value: String, isLarge: Bool)] = [:]
for entry in transition.historyView.filteredEntries {
switch entry {
case let .MessageEntry(message, _, _, _, _, _):
@@ -2393,7 +2396,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
if let reactions = message.reactionsAttribute {
for recentPeer in reactions.recentPeers {
if recentPeer.isUnseen {
updatedIncomingReactions[message.id] = recentPeer.value
updatedIncomingReactions[message.id] = (recentPeer.value, recentPeer.isLarge)
}
}
}
@@ -2405,7 +2408,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
if let reactions = message.0.reactionsAttribute {
for recentPeer in reactions.recentPeers {
if recentPeer.isUnseen {
updatedIncomingReactions[message.0.id] = recentPeer.value
updatedIncomingReactions[message.0.id] = (recentPeer.value, recentPeer.isLarge)
}
}
}
@@ -2426,7 +2429,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
}
}
if previousReaction != updatedReaction {
if previousReaction != updatedReaction.value {
newIncomingReactions[message.id] = updatedReaction
}
}
@@ -2441,7 +2444,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
}
}
if previousReaction != updatedReaction {
if previousReaction != updatedReaction.value {
newIncomingReactions[message.0.id] = updatedReaction
}
}
@@ -2599,52 +2602,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
}
if !newIncomingReactions.isEmpty, let chatDisplayNode = strongSelf.controllerInteraction.chatControllerNode() as? ChatControllerNode {
var visibleNewIncomingReactionMessageIds: [MessageId] = []
strongSelf.forEachVisibleItemNode { itemNode in
guard let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item, let updatedReaction = newIncomingReactions[item.content.firstMessage.id] else {
return
}
visibleNewIncomingReactionMessageIds.append(item.content.firstMessage.id)
if let availableReactions = item.associatedData.availableReactions, let targetView = itemNode.targetReactionView(value: updatedReaction) {
for reaction in availableReactions.reactions {
guard let centerAnimation = reaction.centerAnimation else {
continue
}
guard let aroundAnimation = reaction.aroundAnimation else {
continue
}
if reaction.value == updatedReaction {
let standaloneReactionAnimation = StandaloneReactionAnimation()
chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
chatDisplayNode.addSubnode(standaloneReactionAnimation)
standaloneReactionAnimation.frame = chatDisplayNode.bounds
standaloneReactionAnimation.animateReactionSelection(
context: strongSelf.context,
theme: item.presentationData.theme.theme,
reaction: ReactionContextItem(
reaction: ReactionContextItem.Reaction(rawValue: reaction.value),
appearAnimation: reaction.appearAnimation,
stillAnimation: reaction.selectAnimation,
listAnimation: centerAnimation,
largeListAnimation: reaction.activateAnimation,
applicationAnimation: aroundAnimation,
largeApplicationAnimation: reaction.effectAnimation
),
targetView: targetView,
completion: { [weak standaloneReactionAnimation] in
standaloneReactionAnimation?.removeFromSupernode()
}
)
}
}
}
}
if !newIncomingReactions.isEmpty {
let messageIds = Array(newIncomingReactions.keys)
let visibleNewIncomingReactionMessageIds = strongSelf.displayUnseenReactionAnimations(messageIds: messageIds)
if !visibleNewIncomingReactionMessageIds.isEmpty {
strongSelf.unseenReactionsProcessingManager.add(visibleNewIncomingReactionMessageIds)
}
@@ -2696,6 +2657,79 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
}
}
private func displayUnseenReactionAnimations(messageIds: [MessageId]) -> [MessageId] {
guard let chatDisplayNode = self.controllerInteraction.chatControllerNode() as? ChatControllerNode else {
return []
}
var visibleNewIncomingReactionMessageIds: [MessageId] = []
self.forEachVisibleItemNode { itemNode in
guard let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item, let reactionsAttribute = item.content.firstMessage.reactionsAttribute, messageIds.contains(item.content.firstMessage.id) else {
return
}
var selectedReaction: (String, Bool)?
for recentPeer in reactionsAttribute.recentPeers {
if recentPeer.isUnseen {
selectedReaction = (recentPeer.value, recentPeer.isLarge)
break
}
}
guard let (updatedReaction, updatedReactionIsLarge) = selectedReaction else {
return
}
visibleNewIncomingReactionMessageIds.append(item.content.firstMessage.id)
if let availableReactions = item.associatedData.availableReactions, let targetView = itemNode.targetReactionView(value: updatedReaction) {
for reaction in availableReactions.reactions {
guard let centerAnimation = reaction.centerAnimation else {
continue
}
guard let aroundAnimation = reaction.aroundAnimation else {
continue
}
if reaction.value == updatedReaction {
let standaloneReactionAnimation = StandaloneReactionAnimation()
chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
chatDisplayNode.addSubnode(standaloneReactionAnimation)
standaloneReactionAnimation.frame = chatDisplayNode.bounds
standaloneReactionAnimation.animateReactionSelection(
context: self.context,
theme: item.presentationData.theme.theme,
reaction: ReactionContextItem(
reaction: ReactionContextItem.Reaction(rawValue: reaction.value),
appearAnimation: reaction.appearAnimation,
stillAnimation: reaction.selectAnimation,
listAnimation: centerAnimation,
largeListAnimation: reaction.activateAnimation,
applicationAnimation: aroundAnimation,
largeApplicationAnimation: reaction.effectAnimation
),
isLarge: updatedReactionIsLarge,
targetView: targetView,
addStandaloneReactionAnimation: { [weak self] standaloneReactionAnimation in
guard let strongSelf = self, let chatDisplayNode = strongSelf.controllerInteraction.chatControllerNode() as? ChatControllerNode else {
return
}
chatDisplayNode.messageTransitionNode.addMessageStandaloneReactionAnimation(messageId: item.message.id, standaloneReactionAnimation: standaloneReactionAnimation)
standaloneReactionAnimation.frame = chatDisplayNode.bounds
chatDisplayNode.addSubnode(standaloneReactionAnimation)
},
completion: { [weak standaloneReactionAnimation] in
standaloneReactionAnimation?.removeFromSupernode()
}
)
}
}
}
}
return visibleNewIncomingReactionMessageIds
}
public func updateLayout(transition: ContainedViewLayoutTransition, updateSizeAndInsets: ListViewUpdateSizeAndInsets) {
self.updateLayout(transition: transition, updateSizeAndInsets: updateSizeAndInsets, additionalScrollDistance: 0.0, scrollToTop: false, completion: {})
}
@@ -2964,6 +2998,29 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
return resultMessages
}
func isMessageVisible(id: MessageId) -> Bool {
var found = false
self.forEachVisibleItemNode { itemNode in
if !found, let itemNode = itemNode as? ListViewItemNode {
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
switch item.content {
case let .message(message, _, _ , _, _):
if message.id == id {
found = true
}
case let .group(messages):
for message in messages {
if message.0.id == id {
found = true
}
}
}
}
}
}
return found
}
private var selectionPanState: (selecting: Bool, initialMessageId: MessageId, toggledMessageIds: [[MessageId]])?
private var selectionScrollActivationTimer: SwiftSignalKit.Timer?
private var selectionScrollDisplayLink: ConstantDisplayLinkAnimator?