openMessage() was running a live imapClient.setFlag(SEEN) IMAP round trip
(connection + STORE) before returning whenever a message's body was already
cached but unread — purely to mark it read on the server. That network call
sat on the reader's critical path even though nothing needed for rendering
(body/attachments) required it, making "open an already-downloaded message"
feel slow (#148).
The local isRead flag is now set immediately (optimistic, local-only) and
openMessage returns without awaiting the SEEN push. The push itself runs on
a new application-lifetime backgroundScope (same CoroutineScope(SupervisorJob()
+ Dispatchers.IO) pattern already used by LibreMailApplication.appScope and
IdleService.scope), with a bounded retry (3 attempts, short backoff) since
today's folder sync deliberately never overwrites local read/star flags with
server state (see MessageDao.updateHeaderContent) and therefore would not
otherwise re-drive a push that never reached the server.
Closes#148
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>