mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-28 12:04:11 +00:00
dual snapshot animation
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ChatItem.ID>()
|
||||
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
|
||||
|
||||
|
||||
@@ -171,17 +171,32 @@ struct ReverseList<Item: Identifiable & Hashable & Sendable, Content: View>: UIV
|
||||
Task { representer.scrollState = .atDestination }
|
||||
}
|
||||
|
||||
func update(items: Array<Item>) {
|
||||
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<Item>, animated: Bool, completion: (() -> Void)? = nil) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user