fix code review issues: deferral date format, storeFlags SELECT, event loop leaks, GTD selection tracking

- fix deferral resurfacing using VTODOParser.formatDateOnly instead of ISO8601 (date format mismatch)
- add SELECT mailbox before UID STORE in storeFlags (IMAP protocol requirement)
- pass credentials to SyncCoordinator so IDLE monitoring activates
- add selectedItem tracking to MailViewModel, wire List selection in GTD views
- fix startPeriodicSync to sleep-first, preventing duplicate sync on launch
- add deinit cleanup for EventLoopGroup in IMAPConnection, SMTPConnection
- use separate IMAP client for attachment downloads, avoid shared connection interference
- remove [weak self] from IMAPIdleClient actor Task to prevent orphaned connections
- fix isGTDPerspective to check selectedMailbox instead of items.isEmpty
- fix fetchBody to use complete RFC822 fetch instead of BODY[TEXT]
- reuse single IMAP connection per ActionQueue.flush() batch
- add requiresIMAP to ActionPayload for connection batching
- load task categories from label store instead of hardcoded empty array
- suppress NIOSSLHandler Sendable warnings via Package.swift unsafeFlags
- fix unused variable warnings across codebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-14 23:13:46 +01:00
parent 3b82e6cd95
commit 10b7cb2fd2
12 changed files with 140 additions and 82 deletions
@@ -1,6 +1,6 @@
import Foundation
import NIO
@preconcurrency import NIOSSL
import NIOSSL
import Models
actor SMTPConnection {
@@ -19,6 +19,10 @@ actor SMTPConnection {
self.responseHandler = SMTPResponseHandler()
}
deinit {
try? group.syncShutdownGracefully()
}
func connect() async throws -> SMTPResponse {
let handler = responseHandler
let hostname = host
@@ -26,11 +30,11 @@ actor SMTPConnection {
let bootstrap: ClientBootstrap
if security == .ssl {
let sslContext = try NIOSSLContext(configuration: TLSConfiguration.makeClientConfiguration())
nonisolated(unsafe) let sslHandler = try NIOSSLClientHandler(context: sslContext, serverHostname: hostname)
bootstrap = ClientBootstrap(group: group)
.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.channelInitializer { channel in
let sslHandler = try! NIOSSLClientHandler(context: sslContext, serverHostname: hostname)
return channel.pipeline.addHandlers([sslHandler, handler])
channel.pipeline.addHandlers([sslHandler, handler])
}
} else {
// STARTTLS: start plain, upgrade later