Skip to content

Commit

Permalink
Merge pull request #821 from Infomaniak/actor
Browse files Browse the repository at this point in the history
fix: Use actor to refresh threads
  • Loading branch information
PhilippeWeidmann committed Jun 21, 2023
2 parents 7c46e1a + 460f20a commit e96529d
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 17 deletions.
3 changes: 3 additions & 0 deletions Mail/Views/Thread List/ThreadListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ struct ThreadListView: View {
guard let folder = newFolder else { return }

viewModel.isLoadingPage = false

Task {
await viewModel.mailboxManager.cancelRefresh()

fetchingTask?.cancel()
_ = await fetchingTask?.result
fetchingTask = nil
Expand Down
11 changes: 2 additions & 9 deletions Mail/Views/Thread List/ThreadListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,8 @@ final class DateSection: Identifiable, Equatable {
isLoadingPage = true
}

await tryOrDisplayError {
try await mailboxManager.threads(folder: folder.freezeIfNeeded()) {
Task {
withAnimation {
self.isLoadingPage = false
}
}
}
}
await mailboxManager.refresh(folder: folder.freezeIfNeeded())

withAnimation {
isLoadingPage = false
}
Expand Down
6 changes: 3 additions & 3 deletions MailCore/Cache/DraftManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public class DraftManager {

private func refreshDraftFolder(latestSendDate: Date?, mailboxManager: MailboxManager) async throws {
if let draftFolder = mailboxManager.getFolder(with: .draft)?.freeze() {
try await mailboxManager.threads(folder: draftFolder)
await mailboxManager.refresh(folder: draftFolder)

if let latestSendDate = latestSendDate {
/*
Expand All @@ -165,7 +165,7 @@ public class DraftManager {
*/
let delay = latestSendDate.timeIntervalSinceNow
try await Task.sleep(nanoseconds: UInt64(1_000_000_000 * max(Double(delay), 1.5)))
try await mailboxManager.threads(folder: draftFolder)
await mailboxManager.refresh(folder: draftFolder)
}

await mailboxManager.deleteOrphanDrafts()
Expand All @@ -179,7 +179,7 @@ public class DraftManager {
try await mailboxManager.delete(draft: liveDraft.freeze())
await IKSnackBar.showSnackBar(message: MailResourcesStrings.Localizable.snackbarDraftDeleted)
if let draftFolder = mailboxManager.getFolder(with: .draft)?.freeze() {
try await mailboxManager.threads(folder: draftFolder)
await mailboxManager.refresh(folder: draftFolder)
}
}
}
Expand Down
23 changes: 19 additions & 4 deletions MailCore/Cache/MailboxManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class MailboxManager: ObservableObject {
public private(set) var apiFetcher: MailApiFetcher
private let backgroundRealm: BackgroundRealm

private lazy var refreshActor = RefreshActor(mailboxManager: self)

public init(mailbox: Mailbox, apiFetcher: MailApiFetcher) {
self.mailbox = mailbox
self.apiFetcher = apiFetcher
Expand Down Expand Up @@ -222,7 +224,7 @@ public class MailboxManager: ObservableObject {

public func flushFolder(folder: Folder) async throws -> Bool {
let response = try await apiFetcher.flushFolder(mailbox: mailbox, folderId: folder.id)
try await threads(folder: folder)
await refresh(folder: folder)
return response
}

Expand All @@ -236,7 +238,7 @@ public class MailboxManager: ObservableObject {

for folder in orderedSet {
guard let impactedFolder = folder as? Folder else { continue }
try await threads(folder: impactedFolder)
await refresh(folder: impactedFolder)
}
}

Expand Down Expand Up @@ -637,7 +639,10 @@ public class MailboxManager: ObservableObject {
public func messages(folder: Folder) async throws {
guard !Task.isCancelled else { return }

let previousCursor = folder.cursor
let realm = getRealm()
let freshFolder = folder.fresh(using: realm)

let previousCursor = freshFolder?.cursor
var messagesUids: MessagesUids

if previousCursor == nil {
Expand Down Expand Up @@ -892,7 +897,7 @@ public class MailboxManager: ObservableObject {
let folders = Set(threads.compactMap(\.folder))
for thread in threads {
do {
try thread.recomputeOrFail()
try thread.recomputeOrFail()
} catch {
SentrySDK.capture(message: "Thread has nil lastMessageFromFolderDate") { scope in
scope.setContext(value: ["dates": "\(thread.messages.map { $0.date })",
Expand Down Expand Up @@ -1173,6 +1178,16 @@ public class MailboxManager: ObservableObject {
}
}

// MARK: - RefreshActor

public func refresh(folder: Folder) async {
await refreshActor.refresh(folder: folder)
}

public func cancelRefresh() async {
await refreshActor.cancelRefresh()
}

// MARK: - Utilities

struct MessagePropertiesOptions: OptionSet {
Expand Down
47 changes: 47 additions & 0 deletions MailCore/Cache/RefreshActor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2022 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 <http://www.gnu.org/licenses/>.
*/

import Foundation

public actor RefreshActor {
weak var mailboxManager: MailboxManager?

private var refreshTask: Task<Void, Never>?

public init(mailboxManager: MailboxManager) {
self.mailboxManager = mailboxManager
}

public func refresh(folder: Folder) async {
await cancelRefresh()

refreshTask = Task {
await tryOrDisplayError {
try await mailboxManager?.threads(folder: folder)
refreshTask = nil
}
}
_ = await refreshTask?.result
}

public func cancelRefresh() async {
refreshTask?.cancel()
_ = await refreshTask?.result
refreshTask = nil
}
}
2 changes: 1 addition & 1 deletion MailNotificationServiceExtension/NotificationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class NotificationService: UNNotificationServiceExtension {
// We do nothing if we don't have an initial cursor
return nil
}
try await mailboxManager.threads(folder: inboxFolder.freezeIfNeeded())
await mailboxManager.refresh(folder: inboxFolder.freezeIfNeeded())

@ThreadSafe var message = mailboxManager.getRealm().object(ofType: Message.self, forPrimaryKey: uid)

Expand Down

0 comments on commit e96529d

Please sign in to comment.