From 5a78f11c8b7294cbf4b1e51cd253d0c57d3372db Mon Sep 17 00:00:00 2001 From: Diogo Date: Sat, 19 Oct 2024 09:36:03 +0100 Subject: [PATCH] jump to first unread --- apps/ios/Shared/Views/Chat/ChatView.swift | 23 ++++++++++++++++- apps/ios/Shared/Views/Chat/ReverseList.swift | 26 +++++++++++--------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index c26642ac45..087c530fcd 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -174,7 +174,6 @@ struct ChatView: View { .onChange(of: chatModel.chatId) { cId in showChatInfoSheet = false selectedChatItems = nil - scrollModel.scrollToBottom() stopAudioPlayer() if let cId { if let c = chatModel.getChat(cId) { @@ -371,6 +370,28 @@ struct ChatView: View { } ChatView.FloatingButtonModel.shared.totalUnread = chat.chatStats.unreadCount sectionModel.resetSections(items: im.reversedChatItems) + + let minUnreadItemId = chat.chatStats.minUnreadItemId + if minUnreadItemId > 0, !im.reversedChatItems.contains(where: { $0.id == minUnreadItemId }) { + Task { + if let reversedPage = await loadItemsAround(chat.chatInfo, minUnreadItemId) { + await MainActor.run { + let reversedPageToAppend = self.sectionModel.handleSectionInsertion( + candidateSection: .current, + reversedPage: reversedPage, + allItems: im.reversedChatItems + ) + im.reversedChatItems.append(contentsOf: reversedPageToAppend) + + withAnimation { + scrollModel.scrollToItem(id: minUnreadItemId, position: .middle) + } + } + } + } + } else { + scrollModel.scrollToBottom() + } } private func searchToolbar() -> some View { diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift index 97b9f54526..04498f65d1 100644 --- a/apps/ios/Shared/Views/Chat/ReverseList.swift +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -17,7 +17,7 @@ enum ChatScrollDirection { } enum ChatSection: CaseIterable { - case main + case current case destination case bottom } @@ -44,10 +44,10 @@ struct ReverseList: UIViewControllerRepresentable { switch destination { case .nextPage: controller.scrollToNextPage() - case let .item(id): - controller.scrollToItem(id: id) + case let .item(id, position, animated): + controller.scrollToItem(id: id, position: position, animated: animated) case .bottom: - controller.scroll(to: 0, position: .top, section: .bottom) + controller.scroll(to: 0, position: .top, section: .bottom, shouldTryAnimate: true) } } else { controller.update(items: items) @@ -185,22 +185,22 @@ struct ReverseList: UIViewControllerRepresentable { } /// Scrolls to a given item - func scrollToItem(id: Int64) { + func scrollToItem(id: Int64, position: UITableView.ScrollPosition, animated: Bool) { if let loadedIndex = self.representer.items.firstIndex(where: { $0.id == id }) { let ci = representer.items[loadedIndex] if let indexPath = dataSource.indexPath(for: ci), let section = dataSource.sectionIdentifier(for: indexPath.section) { - self.scroll(to: indexPath.row, position: .bottom, section: section) + self.scroll(to: indexPath.row, position: position, section: section, shouldTryAnimate: animated) } } } /// Scrolls to Item at index path /// - Parameter indexPath: Item to scroll to - will scroll to beginning of the list, if `nil` - func scroll(to index: Int?, position: UITableView.ScrollPosition, section: ChatSection) { + func scroll(to index: Int?, position: UITableView.ScrollPosition, section: ChatSection, shouldTryAnimate: Bool) { var animated = false if #available(iOS 16.0, *) { - animated = true + animated = shouldTryAnimate } if let index, let sectionIndex = dataSource.index(for: section), tableView.numberOfRows(inSection: sectionIndex) != 0 { tableView.scrollToRow( @@ -377,7 +377,7 @@ class ReverseListScrollModel: ObservableObject { enum State: Equatable { enum Destination: Equatable { case nextPage - case item(ChatItem.ID) + case item(ChatItem.ID, UITableView.ScrollPosition, Bool) case bottom } @@ -395,8 +395,8 @@ class ReverseListScrollModel: ObservableObject { state = .scrollingTo(.bottom) } - func scrollToItem(id: ChatItem.ID) { - state = .scrollingTo(.item(id)) + func scrollToItem(id: ChatItem.ID, position: UITableView.ScrollPosition? = .bottom, animated: Bool = true) { + state = .scrollingTo(.item(id, position ?? .bottom, animated)) } } @@ -413,6 +413,10 @@ class ReverseListSectionModel: ObservableObject { func getSectionsOrdered() -> [ChatSection] { var orderedSections: [ChatSection] = [.bottom] + if (sections.contains(.current)) { + orderedSections.append(.current) + } + if (sections.contains(.destination)) { orderedSections.append(.destination) }