diff --git a/docs/parity/03-email-viewer.md b/docs/parity/03-email-viewer.md index bda8256a..45dd2ce8 100644 --- a/docs/parity/03-email-viewer.md +++ b/docs/parity/03-email-viewer.md @@ -12,7 +12,7 @@ RN has a solid single-message reader (WebView body with CSP, shrink-to-fit + pin - What RN does: the list collapses same-thread rows to the newest message with a count badge (`src/screens/EmailListScreen.tsx:224-238`, default `disableThreading: false` at `src/stores/settings-store.ts:266`), the row opens `EmailThreadScreen` with a single `emailId` (`App.tsx:145-151`), and the screen only ever shows that one message (`src/screens/EmailThreadScreen.tsx:113-120`, `685-840`). `getThread` exists in `src/api/email.ts:448` but is only used by a test. Older messages of a thread cannot be opened at all unless the user turns on "Disable Thread Grouping". - Fix hint: on open, call `getThread(threadId, ownerAccountId)` + `getFullEmails(ids)` and render a vertical list of collapsible message cards inside the pane (newest + unread expanded), reusing `EmailBodyView` per card; keep the horizontal pager for thread-to-thread navigation. -- [ ] **Pager shows the wrong message (or nothing) when the opened email is not in the store list** — `P1` — `rn-only-bug` +- [x] **Pager shows the wrong message (or nothing) when the opened email is not in the store list — fixed in c8be383** — `P1` — `rn-only-bug` - What WEB does: the viewer renders `selectedEmail` directly; prev/next are derived from the current list (`components/email/email-viewer.tsx:5220-5279`). - What RN does: the pager is a `FlatList` over `useEmailStore(s => s.emails)` and the initial index is `Math.max(0, emails.findIndex(id))` (`src/screens/EmailThreadScreen.tsx:128-133`, `535-572`). `UnifiedInboxScreen` keeps its own local list and never writes the store (`src/screens/UnifiedInboxScreen.tsx:35-50`, `61-84`), `ContactActivity` navigates with ids from a contact search (`src/components/contacts/ContactActivity.tsx:170-177`). In both cases the opened id is absent from `emails`, so the visible pane is `emails[0]` (a different mailbox's first message, or blank when the list is empty) while the toolbar/mark-read/delete act on `activeEmailId`. - Fix hint: when `route.params.emailId` is not in `emails`, render a single-item pager (`data=[{id: emailId}]`) and disable prev/next; or have the unified inbox / contact activity pass their own id list through route params. @@ -26,12 +26,12 @@ RN has a solid single-message reader (WebView body with CSP, shrink-to-fit + pin ### Body rendering & sanitisation -- [ ] **HTML-only messages are rendered (and quoted) as raw HTML source — native issue #46 "email preview shows css"** — `P1` — `bug` +- [x] **HTML-only messages are rendered (and quoted) as raw HTML source — native issue #46 "email preview shows css" — fixed in 06742ef** — `P1` — `bug` - What WEB does: per RFC 8621 §4.1.4 an HTML-only message exposes the same part in `textBody` and `htmlBody`; WEB checks `hasDistinctTextBody` (different partIds) before preferring the text alternative, and routes by the part's `type` (`components/email/email-viewer.tsx:1727-1747`, `components/email/thread-conversation-view.tsx:332-346`; changelog 1.6.3 "Render HTML-only emails", "Render plain-text-only emails as text, not HTML"). - What RN does: `extractTextBody` returns the html part's value for HTML-only mail, then `rawHtml = html && (!text || hasMeaningfulHtmlBody(html)) ? html : null` (`src/components/EmailBodyView.tsx:43-57`, `504-511`). For any HTML-only message whose markup fails `MEANINGFUL_HTML_RE` (`src/lib/email-html.ts:353-362`, e.g. a `
`/`

` body without `style=`), `rawHtml` is null and the raw source — tags, ``, CSS — is shown as plain text. The same value feeds the reply quote: `plainTextBody()` (`src/screens/EmailThreadScreen.tsx:59-65`, `377`) so replies to HTML-only mail quote escaped HTML source. - Fix hint: compare `textBody[0].partId !== htmlBody[0].partId` (and `part.type === 'text/html'`) before treating `text` as an alternative; in `navigateCompose` pass `htmlBody` (and let `buildInitialHtml` use it) or convert with `htmlToPlainText` (`src/lib/compose-html.ts:108`) when the only body is HTML. -- [ ] **`