Message Viewer
Relevant source files
The following files were used as context for generating this wiki page:The Message Viewer is the primary UI component responsible for rendering email content, handling message metadata, and providing user actions such as replying, forwarding, or moving messages. It displays a selected message from the message list and manages security features like resource sanitization and privacy banners.
Sources: crates/mailiner-app/src/components/messageview.rs:163-228
Core Architecture
The Message Viewer utilizes a reactive state machine to handle the lifecycle of a selected email. It interacts with the AppContext to track the currently selected message and its loading status.
State Management
The viewer operates in one of four states defined by MessageViewState:
- Empty: No message is currently selected.
- Loading: A message has been selected and the content is being fetched.
- Ready: The message content is fully loaded and formatted for display.
- Error: An error occurred during the loading process.
Sources: crates/mailiner-app/src/components/messageview.rs:154-161, crates/mailiner-app/src/components/messageview.rs:205-228
Component Relationship
The viewer is composed of a header for metadata/actions and a content host for the message body.
The diagram shows the sub-components of the Message Viewer and the logical isolation of message content via the Shadow Root.
Sources: crates/mailiner-app/src/components/messageview.rs:163-228
Content Rendering and Isolation
To prevent email CSS from bleeding into the main application UI and to ensure security, the Message Viewer renders sanitized HTML inside an open Shadow Root.
Shadow DOM Mounting
The mount_shadow_html function performs the following steps:
- Locates the host element (
mailiner-message-content). - Attaches or retrieves an open
ShadowRoot. - Parses the sanitized HTML using
DOMParser. - Adopts the resulting document element into the main document.
- Appends a reset stylesheet to the shadow root to ensure consistent layout (e.g., removing default margins).
Sources: crates/mailiner-app/src/components/messageview.rs:32-83
Privacy Protection
The system blocks remote resources (images and styles) by default to protect user privacy. If the formatter detects stripped remote attributes, the viewer displays a privacy banner allowing the user to opt-in for that specific message.
Sources: crates/mailiner-app/src/components/messageview.rs:188-228, crates/mailiner-app/src/formatter/html.rs:49-54
Message Formatting Pipeline
The formatting pipeline transforms raw message parts into safe, displayable HTML.
The sequence shows the transformation from raw message parts to sanitized HTML results.
Sources: crates/mailiner-app/src/formatter/mod.rs:38-50, crates/mailiner-app/src/formatter/html.rs:24-85
Formatter Logic
| Feature | Implementation Detail |
|---|---|
| Preference | HTML parts are preferred over plain text parts. |
| CID Resolution | cid: URLs are converted to base64 data URLs using safe image types. |
| Sanitization | Uses ammonia to strip scripts, iframes, and SVG/Math tags. |
| Linkification | Plain text parts are automatically linkified using linkify. |
| CSS Safety | Styles are sanitized to strip url() references unless explicitly allowed. |
Sources: crates/mailiner-app/src/formatter/mod.rs:38-66, crates/mailiner-app/src/formatter/html.rs:24-100, crates/mailiner-html/src/lib.rs:136-160
User Actions and Interaction
The MessageHeader component provides controls for message management. These actions often dispatch CoreEvent signals to the background logic.
Supported Actions
- Reply / Reply All / Forward: Construcs a new draft using the
mailiner-composercrate and the currently loaded message. - Mark Read/Unread: Updates the
\Seenflag on the server for selected messages. - Move to Folder: Transfers selected messages to a different mailbox.
- Trash/Delete: Moves messages to the Trash folder or performs a permanent deletion if already in Trash.
Sources: crates/mailiner-app/src/components/messageview.rs:245-420
Viewport Navigation
The viewer supports keyboard-driven scrolling through the scroll_message_view function.
| Scroll Type | Delta Calculation |
|---|---|
| Line | Moves by a fixed 48px step. |
| Page | Moves by 85% of the viewport height. |
Scrolling uses the browser's smooth behavior. The implementation coalesces rapid key presses (within 350ms) to ensure smooth target animation without restarting from mid-flight positions.
Sources: crates/mailiner-app/src/components/messageview.rs:95-152
Data Models
The viewer relies on structured models for envelopes and body parts derived from the IMAP connector.
Message Metadata
The component displays the following fields from the Message model:
- Subject: Truncated if necessary; shows "(no subject)" if empty.
- Recipients: Displays "From", "To", "Cc", and "Bcc" fields with full-address tooltips.
- Date: Formatted as
%d %b %Y, %H:%M.
Sources: crates/mailiner-app/src/components/messageview.rs:24-26, crates/mailiner-app/src/components/messageview.rs:422-430, crates/mailiner-core/src/connector.rs:141-177
The Message Viewer facilitates a secure, reactive interface for email consumption by isolating untrusted content while providing standard mailbox management features.