Skip to content

Feature: preview composer attachments inline (click to open)#378

Open
dealerweb wants to merge 1 commit into
bulwarkmail:mainfrom
dealerweb:pr/composer-attachment-preview
Open

Feature: preview composer attachments inline (click to open)#378
dealerweb wants to merge 1 commit into
bulwarkmail:mainfrom
dealerweb:pr/composer-attachment-preview

Conversation

@dealerweb
Copy link
Copy Markdown
Contributor

Summary

The message viewer already lets you click an attachment to preview it, but the composer/draft view only offered download/remove. This adds click-to-preview parity: clicking an attachment chip in the composer opens the same FilePreviewModal.

Changes

  • The attachment chip's name/size becomes a button when the attachment has content (a local File, or - for forwarded attachments - an uploaded blob) and the type is previewable (isFilePreviewable); it is never clickable mid-upload. The remove (X) button is unchanged.
  • getFileContent prefers the in-memory File (no network round-trip) and falls back to composerClient.fetchBlob for forwarded attachments (blobId only).
  • Reuses the existing FilePreviewModal, so all rendering (image / PDF / pdf.js-mobile / video / audio / text / html) and the open-in-new-tab inline-safe-MIME gate come for free.

Type of Change

  • New feature (non-breaking change that adds functionality)

Checklist

  • Contributing Guide read
  • Code follows project style and conventions
  • npm run typecheck && npm run lint passes
  • Build passes (npm run build)
  • Changes tested locally
  • Translations updated (locales/) - n/a, no new strings (the tooltip reuses the filename)

Notes for Reviewers

  • No new dependencies and no new locale keys.
  • Security: adds no new egress. Preview rendering and the open-in-new-tab gate are the modal's (html renders in <iframe sandbox="">; the open-in-new-tab button is gated by isMimeTypeSafeForInlinePreview). The local-file download path uses an <a download> (forces a save, never executes), so a script-bearing attachment can't run in-origin.
  • next lint errors on Next 16 repo-wide (unrelated); ESLint on the changed file passes (one pre-existing exhaustive-deps warning, not from this change).
  • Tested on a live Stalwart deployment: dragging files into a new mail / draft, clicking the chip opens the preview; remove still works.

Clicking an attachment chip in the composer now opens the same FilePreviewModal
the message viewer uses, instead of offering only download/remove. The chip
becomes clickable once the attachment has content (a local File, or an uploaded
blob for forwarded attachments) and the type is previewable.

- getFileContent prefers the in-memory File (no network round-trip) and falls
  back to composerClient.fetchBlob for forwarded attachments (blobId only).
- Previewability (isFilePreviewable) and the open-in-new-tab safety gate are
  handled inside the modal, so this adds no new egress/attack surface; the local
  download path uses an <a download> (forces a save, never executes).
- No new dependencies and no new locale keys.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant