From 5b18da4fe6c2b28f48f892f05953c6a9a22f52b8 Mon Sep 17 00:00:00 2001 From: Levitating Pineapple Date: Fri, 16 Aug 2024 19:11:47 +0300 Subject: [PATCH] dual snapshot animation --- apps/ios/Shared/Model/ChatModel.swift | 13 ++++---- apps/ios/Shared/Views/Chat/ChatView.swift | 23 --------------- apps/ios/Shared/Views/Chat/ReverseList.swift | 31 +++++++++++++++----- 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index ed3a5a3316..4b391b727e 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -450,13 +450,14 @@ final class ChatModel: ObservableObject { } return false } else { - var ci = cItem - if let status = chatItemStatuses.removeValue(forKey: ci.id), case .sndNew = ci.meta.itemStatus { - ci.meta.itemStatus = status + withConditionalAnimation(itemAnimation()) { + var ci = cItem + if let status = chatItemStatuses.removeValue(forKey: ci.id), case .sndNew = ci.meta.itemStatus { + ci.meta.itemStatus = status + } + im.reversedChatItems.insert(ci, at: hasLiveDummy ? 1 : 0) + im.itemAdded = true } - if itemAnimation() != nil { FadeInChatItem.items.insert(ci.id) } - im.reversedChatItems.insert(ci, at: hasLiveDummy ? 1 : 0) - im.itemAdded = true return true } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 3b3962ccd5..655dd8aaed 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -413,7 +413,6 @@ struct ChatView: View { revealedChatItem: $revealedChatItem, selectedChatItems: $selectedChatItems ) - .modifier(FadeInChatItem(id: ci.id)) .onAppear { floatingButtonModel.appeared(viewId: ci.viewId) } @@ -1551,28 +1550,6 @@ private func buildTheme() -> AppTheme { } } -struct FadeInChatItem: ViewModifier { - static var items = Set() - private let chatItemId: ChatItem.ID - @State private var isVisible: Bool - - init(id: ChatItem.ID) { - chatItemId = id - isVisible = !Self.items.contains(chatItemId) - } - - func body(content: Content) -> some View { - content - .opacity(isVisible ? 1 : 0) - .onAppear { - if !isVisible { - Self.items.remove(chatItemId) - withAnimation(.easeInOut(duration: 0.5)) { isVisible = true } - } - } - } -} - struct ToggleNtfsButton: View { @ObservedObject var chat: Chat diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift index 39a968f884..15bb31422b 100644 --- a/apps/ios/Shared/Views/Chat/ReverseList.swift +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -171,17 +171,32 @@ struct ReverseList: UIV Task { representer.scrollState = .atDestination } } - func update(items: Array) { + var updateInProgress = false + + func update(items: [Item]) { + if updateInProgress { return } + let itemsAdded = items.count - itemCount + if itemsAdded > 0, itemCount != 0 { + updateInProgress = true + _update(items: Array(items[1...]), animated: false) { + DispatchQueue.main.async { + self._update(items: items, animated: true) { + self.updateInProgress = false + } + } + } + } else { + _update(items: items, animated: false) + } + itemCount = items.count + } + + func _update(items: Array, animated: Bool, completion: (() -> Void)? = nil) { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) snapshot.appendItems(items) - dataSource.defaultRowAnimation = .none - let countChange = abs(items.count - itemCount) - dataSource.apply(snapshot, animatingDifferences: - countChange > 0 && // Avoid animating initial load - countChange < 5 // Avoid animating page loads - ) - itemCount = items.count + dataSource.defaultRowAnimation = animated ? .top : .none + dataSource.apply(snapshot, animatingDifferences: animated, completion: completion) } }