Reply and reply-all now prefill the compose body with the original message quoted as plain text (> lines). New Forward button sets Fwd: subject and the same quoted body, leaving To/Cc empty for the user to fill. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.6 KiB
Done
This file contains tasks which got implemented.
Tasks get moved from next.md to done.md
Tasks
Quote original message in reply, and add Forward button
_reply now passes prefillBody with the original message quoted as plain
text (> line…). New _forward method and Forward toolbar button added;
sets Fwd: subject prefix and prefills the same quoted body with To/Cc empty.
Mark as unread button in email detail
Added mark_email_unread_outlined icon button to EmailDetailScreen toolbar.
Calls setFlag(seen: false) then pops back to the list.
Pull-to-refresh on email list
Wrapped _buildStreamBody in a RefreshIndicator that calls syncEmails.
The empty-state is now a scrollable ListView so the pull gesture works even
when the folder has no messages.
Show email preview snippet in list
Added preview field to EmailThread (populated from the latest email in
_groupIntoThreads). Thread tiles now show subject + a one-line preview
snippet in the subtitle.
Extract TryConnectionButton widget shared by account screens
Extracted lib/ui/widgets/try_connection_button.dart — a stateless widget
rendering the result banner (ok/error text) and the spinner/button. Both
add_account_screen and edit_account_screen now use it, removing ~30 lines
of duplicated UI code.
Extract _batchMoveToRole helper in email_list_screen
_batchArchive() and _batchMarkSpam() collapsed into a shared
_batchMoveToRole(role, notFoundMessage) helper, eliminating ~20 lines of
duplication.
Enable always_use_package_imports lint rule
Added rule to analysis_options.yaml; dart fix --apply converted 125 relative
imports across 33 files to package:sharedinbox/... style automatically.
Replace silent catch (_) with logged errors
5 catch (_) blocks in JMAP push stream setup and 2 in UI screens now use
catch (e) with log(...) via the project's logger.dart wrapper.
The two intentionally silent catches (malformed SSE JSON, Sent folder already
exists) were left as-is since they already had explanatory comments.
Safety hardening before real account use
1. Fix non-PEEK body fetch (silently sets \Seen)
lib/data/repositories/email_repository_impl.dart ~line 163
Change '(BODY[])' → '(BODY.PEEK[])' so fetching the body does not set \Seen
as a side-effect of the IMAP FETCH command.
Same fix at ~line 1696 for attachment part fetches: BODY[partId] → BODY.PEEK[partId].
2. Move to Trash instead of EXPUNGE
lib/data/repositories/email_repository_impl.dart deleteEmail method
Before enqueuing a hard delete, query the local mailboxes cache for a 'trash'-role
folder for that account.
- If found AND the email is not already in Trash: call
moveEmailto that path. - If not found OR already in Trash: fall back to the existing EXPUNGE path.
This makes delete reversible — the user can recover from Trash.
3. Confirmation dialog for delete
Three call sites need a showDialog confirmation before deleting:
a) Delete button in detail view
lib/ui/screens/email_detail_screen.dart ~line 97
Show AlertDialog "Delete this email?" with Cancel / Delete buttons.
b) Batch delete in list view
lib/ui/screens/email_list_screen.dart _batchDelete ~line 268
Show AlertDialog "Delete N emails?" with Cancel / Delete buttons.
c) Swipe-to-delete in list view
lib/ui/screens/email_list_screen.dart Dismissible.onDismissed ~line 436
Use Dismissible.confirmDismiss callback (fires before the item is removed)
to show a confirmation for the right-swipe (delete) direction only.
Return false to cancel and keep the item in the list.