fix double sync race: remove duplicate syncNow calls, add sync guard
- connectAccount() and loadExistingAccount() no longer call syncNow() — the .task modifier on mailView handles initial sync + periodic sync - add isSyncing guard to prevent concurrent syncNow() calls that race on the IMAP connection and cause "Previous command interrupted" - reload mailboxes after each sync (needed on first sync when DB is empty) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -165,11 +165,10 @@ struct ContentView: View {
|
||||
try viewModel.setup(config: config, credentials: credentials)
|
||||
try KeychainService.saveCredentials(credentials, for: config.id)
|
||||
Self.saveAccountConfig(config)
|
||||
// syncNow + startPeriodicSync happen via .task on mailView — don't duplicate
|
||||
Task {
|
||||
await viewModel.syncNow()
|
||||
await viewModel.loadMailboxes(accountId: config.id)
|
||||
viewModel.startObservingThreads(accountId: config.id)
|
||||
viewModel.startPeriodicSync()
|
||||
}
|
||||
} catch {
|
||||
accountSetup.errorMessage = error.localizedDescription
|
||||
@@ -182,11 +181,10 @@ struct ContentView: View {
|
||||
else { return }
|
||||
do {
|
||||
try viewModel.setup(config: config, credentials: credentials)
|
||||
// syncNow + startPeriodicSync happen via .task on mailView — don't duplicate
|
||||
Task {
|
||||
await viewModel.loadMailboxes(accountId: config.id)
|
||||
viewModel.startObservingThreads(accountId: config.id)
|
||||
await viewModel.syncNow()
|
||||
viewModel.startPeriodicSync()
|
||||
}
|
||||
} catch {
|
||||
// Account config exists but setup failed — show account setup
|
||||
|
||||
@@ -201,11 +201,19 @@ final class MailViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
private var isSyncing = false
|
||||
|
||||
func syncNow() async {
|
||||
guard let coordinator else { return }
|
||||
guard let coordinator, !isSyncing else { return }
|
||||
isSyncing = true
|
||||
defer { isSyncing = false }
|
||||
do {
|
||||
try await coordinator.syncNow()
|
||||
syncState = coordinator.syncState
|
||||
// Reload mailboxes after sync (they may have been created on first sync)
|
||||
if let accountConfig {
|
||||
await loadMailboxes(accountId: accountConfig.id)
|
||||
}
|
||||
} catch {
|
||||
let desc = "\(error)"
|
||||
print("[MailViewModel] syncNow failed: \(desc)")
|
||||
|
||||
Reference in New Issue
Block a user