attachments preview overlay, docx/xlsx/odf rendering, composer drag-drop & undo-send UX

Frontend:
- Full-screen attachment preview overlay (AttachmentPreview) for image/pdf/txt
  plus office docs: .docx via docx-preview (rendered live into the sandboxed
  iframe so header/footer VML images survive), .xlsx via xlsx-preview, and
  .odt/.ods/.odp/.odg via a JSZip+DOMParser ODF walker (officeConvert).
- Type-aware attachment icons (green spreadsheet, blue document, red PDF,
  image/archive); new document/image/spreadsheet/print SVGs.
- Composer: drag-drop attachments (body drop inserts images inline, else
  attaches); inserted images are selectable/resizable/deletable (RichTextEditor).
- Undo-send: "Sending…" banner with live "N seconds to Undo" countdown.
- Search result list: pin/archive/delete update correctly; grey-out only for
  search hits; scoped "Search in Trash/Spam".

Backend:
- Search: prefix (search-as-you-type) matching, email-address search, and
  address-first result ordering; Trash/Junk excluded with scoped folder search.
- Attachments: RFC 6266 Content-Disposition for non-ASCII filenames; one-time
  inline image loading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rcj3TpydMTzTSmU7kunzf8
This commit is contained in:
2026-07-26 16:15:49 +02:00
co-authored by Claude Opus 4.8
parent c023cfa15e
commit dd0b089049
22 changed files with 2726 additions and 82 deletions
+9
View File
@@ -49,6 +49,8 @@ export const en = {
"nav.spam": "Spam",
"nav.trash": "Trash",
"nav.search": "Search mail…",
"nav.searchInTrash": "Search in Trash",
"nav.searchInSpam": "Search in Spam",
"search.save": "Save this search",
"search.saved": "Saved searches",
"search.saveNamePrompt": "Name this saved search:",
@@ -61,6 +63,10 @@ export const en = {
"mail.expandAll": "Expand all",
"mail.collapseAll": "Collapse all",
"mail.print": "Print",
"mail.previewPage": "Page {current} / {total}",
"mail.previewResetZoom": "Reset zoom",
"mail.previewPrev": "Previous",
"mail.previewNext": "Next",
"mail.orderOldest": "Oldest first",
"mail.orderNewest": "Newest first",
"filter.all": "All mail",
@@ -120,6 +126,7 @@ export const en = {
"compose.saveDraft": "Save draft",
"compose.closePrompt": "Save this message as a draft?",
"compose.sent": "Message sent.",
"compose.undoIn": "{count} seconds to",
"compose.undo": "Undo",
"compose.sendFailed": "Send failed.",
"compose.savingDraft": "Saving draft…",
@@ -156,6 +163,8 @@ export const en = {
"compose.imageTooLarge": "Image is too large (max 5 MB).",
"compose.attachTooLarge": "File exceeds the 25 MB limit.",
"compose.attachments": "Attachments",
"compose.dropAttach": "Drop to attach",
"compose.dropBody": "Drop image to insert · other files attach",
"wizard.title": "Add mail account",
"wizard.step1": "Your email address",