From 8b8ea1b5704d1d0fca74216a1956e3702bcdb4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Coye=20de=20Brune=CC=81lis?= Date: Thu, 8 Jun 2023 09:20:08 +0200 Subject: [PATCH] feat: observe unread count to disable filtering when reaching zero --- .../ThreadListViewModel+Observation.swift | 44 +++++++++++++++---- .../Thread List/ThreadListViewModel.swift | 10 +++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Mail/Views/Thread List/ThreadListViewModel+Observation.swift b/Mail/Views/Thread List/ThreadListViewModel+Observation.swift index e914b816a3..1f036b8e88 100644 --- a/Mail/Views/Thread List/ThreadListViewModel+Observation.swift +++ b/Mail/Views/Thread List/ThreadListViewModel+Observation.swift @@ -22,14 +22,11 @@ import RealmSwift import SwiftUI extension ThreadListViewModel { - // MARK: - Observe global changes - - func observeChanges(animateInitialThreadChanges: Bool = false) { - stopObserveChanges() - + + private func threadResults() -> Results? { guard let folder = folder.thaw() else { sections = [] - return + return nil } let threadResults: Results @@ -39,8 +36,16 @@ extension ThreadListViewModel { } else { threadResults = folder.threads.sorted(by: \.date, ascending: false) } + + return threadResults + } + + // MARK: - Observe global changes - observationThreadToken = threadResults.observe(on: observeQueue) { [weak self] changes in + func observeChanges(animateInitialThreadChanges: Bool = false) { + stopObserveChanges() + + observationThreadToken = threadResults()?.observe(on: observeQueue) { [weak self] changes in guard let self = self else { return } @@ -99,7 +104,30 @@ extension ThreadListViewModel { // MARK: - Observe unread count + /// Observe the unread count to disable filtering when it reaches 0 func observeUnreadCount() { - // TODO observe the unread count to disable filtering when it reaches 0 + stopObserveUnread() + + observationUnreadToken = threadResults()?.observe(on: observeQueue) { [weak self] changes in + guard let self = self else { + return + } + + switch changes { + case .initial(let changes), .update(let changes, _, _, _): + let count = changes.where { $0.unseenMessages > 0 }.count + Task { + await MainActor.run { + self.unreadCount = count + } + } + case .error: + break + } + } + } + + func stopObserveUnread() { + observationUnreadToken?.invalidate() } } diff --git a/Mail/Views/Thread List/ThreadListViewModel.swift b/Mail/Views/Thread List/ThreadListViewModel.swift index c6580b3c06..72f94b1cd2 100644 --- a/Mail/Views/Thread List/ThreadListViewModel.swift +++ b/Mail/Views/Thread List/ThreadListViewModel.swift @@ -129,6 +129,15 @@ final class DateSection: Identifiable { var observationLastUpdateToken: NotificationToken? let observeQueue = DispatchQueue(label: "com.infomaniak.thread-results", qos: .userInteractive) + @Published var unreadCount: Int = 0 { + didSet { + // Disable filter if we have no unread emails left + if unreadCount == 0 && filterUnreadOn { + filterUnreadOn = false + } + } + } + @Published var filter = Filter.all { didSet { Task { @@ -165,6 +174,7 @@ final class DateSection: Identifiable { lastUpdate = folder.lastUpdate self.isCompact = isCompact observeChanges() + observeUnreadCount() } func fetchThreads() async {