Files
sharedinbox/DONE.md
T
Thomas GüttlerandClaude Sonnet 4.6 eff2940bb8 refactor: extract TryConnectionButton widget shared by account screens
Moved the result banner + spinner/button UI into a new stateless
TryConnectionButton widget, used by both add and edit account screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 16:35:10 +02:00

2.7 KiB

Done

This file contains tasks which got implemented.

Tasks get moved from NEXT.md to DONE.md

Tasks

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 moveEmail to 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.