diff --git a/MailCore/Cache/MailboxManager/MailboxManager+Local.swift b/MailCore/Cache/MailboxManager/MailboxManager+Local.swift
new file mode 100644
index 000000000..698f1735f
--- /dev/null
+++ b/MailCore/Cache/MailboxManager/MailboxManager+Local.swift
@@ -0,0 +1,86 @@
+/*
+ Infomaniak Mail - iOS App
+ Copyright (C) 2024 Infomaniak Network SA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+import Foundation
+
+public extension MailboxManager {
+ enum UpdateType {
+ case seen
+ case star
+
+ func update(message: Message, with value: Bool) {
+ switch self {
+ case .seen:
+ message.seen = value
+ case .star:
+ message.flagged = value
+ }
+ }
+
+ func update(thread: Thread) {
+ switch self {
+ case .seen:
+ thread.updateUnseenMessages()
+ case .star:
+ thread.updateFlagged()
+ }
+ }
+ }
+
+ func updateLocally(_ type: UpdateType, value: Bool, messages: [Message]) async {
+ await backgroundRealm.execute { realm in
+ var updateThreads = Set()
+
+ try? realm.write {
+ for message in messages {
+ guard let liveMessage = realm.object(ofType: Message.self, forPrimaryKey: message.uid) else {
+ continue
+ }
+
+ type.update(message: liveMessage, with: value)
+
+ for thread in liveMessage.threads {
+ updateThreads.insert(thread)
+ }
+ }
+
+ for thread in updateThreads {
+ guard let liveThread = realm.object(ofType: Thread.self, forPrimaryKey: thread.uid) else {
+ continue
+ }
+
+ type.update(thread: liveThread)
+ }
+ }
+ }
+ }
+
+ func markMovedLocally(_ movedLocally: Bool, threads: [Thread]) async {
+ await backgroundRealm.execute { realm in
+ try? realm.write {
+ for thread in threads {
+ guard let liveThread = realm.object(ofType: Thread.self, forPrimaryKey: thread.uid) else {
+ continue
+ }
+
+ liveThread.isMovedOutLocally = movedLocally
+ }
+ }
+ }
+ }
+}
diff --git a/MailCore/Cache/MailboxManager/MailboxManager+Message.swift b/MailCore/Cache/MailboxManager/MailboxManager+Message.swift
index d2fdd3ddb..126383634 100644
--- a/MailCore/Cache/MailboxManager/MailboxManager+Message.swift
+++ b/MailCore/Cache/MailboxManager/MailboxManager+Message.swift
@@ -105,11 +105,18 @@ public extension MailboxManager {
// MARK: Private
func markAsSeen(messages: [Message], seen: Bool) async throws {
- if seen {
- try await apiFetcher.markAsSeen(mailbox: mailbox, messages: messages)
- } else {
- try await apiFetcher.markAsUnseen(mailbox: mailbox, messages: messages)
+ await updateLocally(.seen, value: seen, messages: messages)
+
+ do {
+ if seen {
+ try await apiFetcher.markAsSeen(mailbox: mailbox, messages: messages)
+ } else {
+ try await apiFetcher.markAsUnseen(mailbox: mailbox, messages: messages)
+ }
+ } catch {
+ await updateLocally(.seen, value: !seen, messages: messages)
}
+
try await refreshFolder(from: messages, additionalFolder: nil)
// TODO: Remove after fix
@@ -119,10 +126,16 @@ public extension MailboxManager {
/// Set starred the given messages.
/// - Important: This methods stars only the messages you passes, no processing is done to add duplicates or remove drafts
func star(messages: [Message], starred: Bool) async throws {
- if starred {
- _ = try await star(messages: messages)
- } else {
- _ = try await unstar(messages: messages)
+ await updateLocally(.star, value: starred, messages: messages)
+
+ do {
+ if starred {
+ _ = try await star(messages: messages)
+ } else {
+ _ = try await unstar(messages: messages)
+ }
+ } catch {
+ await updateLocally(.star, value: !starred, messages: messages)
}
}
diff --git a/MailCore/Cache/MailboxManager/MailboxManager+Thread.swift b/MailCore/Cache/MailboxManager/MailboxManager+Thread.swift
index 2ac3ad59d..710c8c4a2 100644
--- a/MailCore/Cache/MailboxManager/MailboxManager+Thread.swift
+++ b/MailCore/Cache/MailboxManager/MailboxManager+Thread.swift
@@ -707,18 +707,4 @@ public extension MailboxManager {
}
}
}
-
- func markMovedLocally(_ movedLocally: Bool, threads: [Thread]) async {
- await backgroundRealm.execute { realm in
- try? realm.write {
- for thread in threads {
- guard let liveThread = realm.object(ofType: Thread.self, forPrimaryKey: thread.uid) else {
- continue
- }
-
- liveThread.isMovedOutLocally = movedLocally
- }
- }
- }
- }
}