feat(compose): rich HTML editor, multipart send, and signatures

Bring rich composition to LibreMail (issues #36, #37, #38, and #23).

#36 HTML editor + toolbar
- New pure, JVM-testable rich-text model (`richtext/`): RichTextContent with
  inline styles + links and block markers ("• ", "N. ", "> "), serializing to a
  narrow email-safe HTML subset and back (fromHtml is a faithful inverse).
- Rich editor in ComposeScreen with a bold/italic/underline, bulleted/numbered
  list, block-quote, and link toolbar, backed by AnnotatedString. Unformatted
  text stays plaintext-only (null HTML) so it feels unchanged and is accessible.
- #23: rounded corners on the compose fields/body via MaterialTheme.shapes.

#37 multipart/alternative + reply/forward quoting
- SmtpSender builds multipart/alternative (text/plain + text/html), nested in
  multipart/mixed when there are attachments; GraphSender sends HTML content.
- HtmlToText produces a readable text/plain fallback; ReplyBuilder quotes HTML
  originals as clean blockquotes (tags stripped) without corruption.
- HTML body persists/restores through drafts and the outbox (new nullable
  bodyHtml columns; Room v9->v10 migration + schema).

#38 signatures
- New signatures table (multiple per account, one default) + repository/DAO;
  migration backfills the existing per-account signature as the default.
- Rich signatures reuse the #36 editor; a Signatures management screen (list,
  add/edit/delete, set default) is linked from per-account settings.
- The account's default signature auto-inserts on new compose / reply / forward
  (honoring the enable toggle), placed above the quote, and stays editable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 00:30:33 -05:00
co-authored by Claude Opus 4.8
parent 64fb82ebd9
commit bee5737ec4
48 changed files with 2954 additions and 109 deletions
+31 -1
View File
@@ -77,6 +77,19 @@
<string name="compose_attach">Attach file</string>
<string name="compose_attachment_remove">Remove attachment</string>
<!-- Compose formatting toolbar -->
<string name="format_bold">Bold</string>
<string name="format_italic">Italic</string>
<string name="format_underline">Underline</string>
<string name="format_bullet_list">Bulleted list</string>
<string name="format_numbered_list">Numbered list</string>
<string name="format_quote">Block quote</string>
<string name="format_link">Insert link</string>
<string name="format_link_title">Insert link</string>
<string name="format_link_url">Link address</string>
<string name="format_link_apply">Link</string>
<string name="format_link_needs_selection">Select some text first, then add a link.</string>
<!-- Drafts -->
<string name="drafts_title">Drafts</string>
<string name="drafts_empty">No drafts</string>
@@ -146,8 +159,25 @@
<!-- Per-account settings -->
<string name="settings_account_title">Account</string>
<string name="settings_signature">Signature</string>
<string name="settings_signature_enable">Append signature</string>
<string name="settings_signature_enable">Append signature automatically</string>
<string name="settings_signature_hint">Your signature</string>
<string name="settings_signatures_manage">Manage signatures</string>
<string name="settings_signatures_summary_none">No signatures yet</string>
<string name="settings_signatures_summary">%1$d signature(s), default: %2$s</string>
<!-- Signatures management -->
<string name="signatures_title">Signatures</string>
<string name="signatures_empty">No signatures yet. Add one to append it to your messages.</string>
<string name="signatures_add">Add signature</string>
<string name="signature_new_title">New signature</string>
<string name="signature_edit_title">Edit signature</string>
<string name="signature_name">Name</string>
<string name="signature_content">Signature</string>
<string name="signature_save">Save</string>
<string name="signature_delete">Delete signature</string>
<string name="signature_default">Default</string>
<string name="signature_make_default">Set as default</string>
<string name="signature_default_badge">Default</string>
<string name="settings_account_notifications">Notifications</string>
<string name="settings_account_new_mail">New mail notifications</string>
<string name="settings_account_new_mail_summary">Show notifications for this account</string>