docs: tick the parity rows the catch-up closed

This commit is contained in:
Linus Rath
2026-10-31 19:06:32 +01:00
parent 633574203f
commit 835508c0c0
8 changed files with 39 additions and 39 deletions
+14 -14
View File
@@ -114,15 +114,15 @@ parses it, nothing stores it), the global locks need no webmail change.
### Report "Open" (2026-10-29)
- [ ] **iOS: reader CSP, composer nonce, `target=_blank` taps, #81 keyboard** — `P2` — `partial` — needs an iOS run (e2e-ios.yml in testing step 4)
- [ ] **iOS push lapses after 7 days without opening the app** — `P2` — `bug` — the extension has no expiry handling (plugins/ios-push/NotificationService.swift), no BGTask; needs a device to verify
- [ ] **Login switch from a deep link or notification keeps the old navigation stack** — `P2` — `bug` — App.tsx:118-122, :141-145, :181-186 switch and navigate on top; question 7
- [ ] **iOS: reader CSP, composer nonce, `target=_blank` taps, #81 keyboard** — `P2` — `partial` — needs an iOS run (e2e-ios.yml in testing step 4) — partly: the iOS build and the tablet sign-in leg pass at 05bc0f56 (run 41216860380); the full run 41220976434 is RESULT PENDING
- [x] **iOS push lapses after 7 days without opening the app** — `P2` — `bug` — the extension has no expiry handling (plugins/ios-push/NotificationService.swift), no BGTask; needs a device to verify — fixed in c704c7e6 (compiled in CI, not run on a device)
- [x] **Login switch from a deep link or notification keeps the old navigation stack** — `P2` — `bug` — App.tsx:118-122, :141-145, :181-186 switch and navigate on top; question 7 — fixed in f9a36b28
- [x] **Sieve editor loses typed text (#1162)** — `P3` — `bug` — src/components/filters/SieveEditorSheet.tsx:35-41 re-seeds on every content change — fixed in 6c3046c8
- [x] **No forward limit (#1155, #1208), no vacation length warning** — `P3` — `missing` — FilterRuleModal.tsx:443-459, VacationSettings.tsx:140-142 — fixed in dcbfc907
- [x] **Other-zone daily series keeps a wrong recurrenceId on the device's DST day** — `P3` — `bug` — src/lib/recurrence-expansion.ts:526-536 builds candidates from device-local fields — fixed in 6e697baa
- [ ] **New strings English-only** — `P3` — `partial` — 331 overlay keys missing in 25 locales, 86 in de; question 6
- [ ] **Org policy, hand-off password** — blocked on the webmail (above)
- [ ] **`C:\ns` junction and the native-sync worktree still exist** — chore — C:\ns points at C:\Users\info\worktrees\native-sync (e6e5e521, on main)
- [x] **New strings English-only** — `P3` — `partial` — 331 overlay keys missing in 25 locales, 86 in de; question 6 — fixed in 3c0d7ad5 (German by hand in 8345be43, the other locales in six commits after it)
- [ ] **Org policy, hand-off password** — blocked on the webmail (above) — partly: hand-off code in ab2e5a60, organisation policy in 9d977773; group-identity scopes, session limits, the external sender chip and recipient confirm, and the org signature's user details are not done
- [ ] **`C:\ns` junction and the native-sync worktree still exist** — chore — C:\ns points at C:\Users\info\worktrees\native-sync (e6e5e521, on main) — kept on purpose (decision 14)
### Webmail bugs from the 2026-10-29 report
@@ -135,16 +135,16 @@ current lines is in "Webmail bugs" at the end of this file.
### UX audit deferred (docs/ux-audit-2026-10.md)
- [x] **U-133 no way out of a hung "Signing in"** — `P2` — `missing` — src/screens/LoginScreen.tsx:218 swallows Back while busy, SigningInStep has no cancel; abortable sign-in, M — fixed in 55d008a2
- [ ] **U-069 recipient suggestions hidden in phone landscape** — `P2` — `missing` — needs a full-screen picker, M (feature)
- [x] **U-069 recipient suggestions hidden in phone landscape** — `P2` — `missing` — needs a full-screen picker, M (feature) — fixed in e1ad5c09
- [x] **U-045 German Prev/Next read "Zurück"/"Weiter"** — `P3` — `bug` — override in locales/rn/de.json — fixed in 25f9b810
- [x] **Plain-text mail dark background fixed at #0a0a0a** — `P3` — `partial` — src/lib/email-html.ts:963 ignores the theme — fixed in 43973608
- [ ] **U-017 system alert vs Dialog, U-136 empty all-day strip, U-124 language order** — product calls, kept deferred unless you say otherwise
- [ ] **U-017 system alert vs Dialog, U-136 empty all-day strip, U-124 language order** — product calls, kept deferred unless you say otherwise — kept (decision 12)
- U-016 scrim token: won't fix (no visible change). U-018 font scale resets navigation: React Native limitation. U-131: done (776447dd).
### iOS test deferred (docs/ios-test-2026-10.md)
- [ ] **Sign-in and features matrices empty; the last three release runs of e2e-ios failed** — `P2` — most failures miss seeded mail, so a reset and seed of stw-v016 comes first (testing step 4)
- [ ] **ios-perf branch never merged** (d13769a9, measured -18% to first inbox) — not part of this run unless you want it
- [ ] **Sign-in and features matrices empty; the last three release runs of e2e-ios failed** — `P2` — most failures miss seeded mail, so a reset and seed of stw-v016 comes first (testing step 4) — partly: stw-v016 reset and seeded, 11 outdated flows fixed in d9d7a466, pod install fixed in 05bc0f56; the full run is RESULT PENDING
- [x] **ios-perf branch never merged** (d13769a9, measured -18% to first inbox) — not part of this run unless you want it — fixed in 36cc49b7
- Blocked on a device or setup: real APNs path through the extension, QR scan with the camera, SSO pairing (needs an external IdP), discovery success (needs DNS records), iOS widgets (WidgetKit extension, L).
- Done: the six app bugs from the test (on main), the webmail hand-off fix 310f910a6.
@@ -153,10 +153,10 @@ current lines is in "Webmail bugs" at the end of this file.
- Fixed on main, unreleased (close after 0.1.87 ships): #80, #82, #83, #84, #86, #87, #89. #81 is fixed in code (01983a38), unchecked on iOS.
- [x] **#91 multi-select without long press** — `P3` — `missing` — EmailListScreen.tsx:190-218; tap on the avatar toggles selection — fixed in 6715df7f
- [x] **#90 custom calendar colours** — `P3` — `missing` — CalendarEditSheet.tsx:222 offers the palette only — fixed in d3f6d6ae
- [ ] **#85 keep the shade open on Delete** — question 1
- [ ] **#58 PGP / S/MIME** — `P3` — L, not in this run
- [ ] **#3 TLS client certificates** — Android done in 0.1.83; iOS has none (L)
- [ ] **PR #66 unified views for a single account** (lucletoffe) — conflicts, no review, the author's question unanswered
- [x] **#85 keep the shade open on Delete** — question 1 — fixed in 2fe83669 (the Android side in 9669e07e)
- [x] **#58 PGP / S/MIME** — `P3` — L, not in this run — fixed in e5027c45 (reading 8aa1d8e0, sending b0997c0a; no Argon2 keys, WKD or legacy S/MIME ciphers)
- [x] **#3 TLS client certificates** — Android done in 0.1.83; iOS has none (L) — fixed in ba150060 (compiled in CI, not run on a device)
- [x] **PR #66 unified views for a single account** (lucletoffe) — conflicts, no review, the author's question unanswered — fixed in 5ecf6f32 (the author's 45b4feeb)
## Dependencies
+1 -1
View File
@@ -258,7 +258,7 @@ RN covers the core single-folder loop well (folder tree incl. shared/group accou
### Tags / keywords
- [ ] **Tag definition features: visibility, nesting/parent, reorder, rename with migration, unknown tags** — `P3` — `partial` — partial in 3194b5e: unknown `$label:` ids listed/removable in TagSheet; deferred: visibility, nesting, reorder, rename migration (device-local tag model, see native issue #1)
- [ ] **Tag definition features: visibility, nesting/parent, reorder, rename with migration, unknown tags** — `P3` — `partial` — partial in 3194b5e: unknown `$label:` ids listed/removable in TagSheet; deferred: visibility, nesting, reorder, rename migration (device-local tag model, see native issue #1) — partly: nesting and sidebar visibility in 585c70a5; reorder and rename with migration still missing
- What WEB does: `visibility: show|unread|hide` (`stores/settings-store.ts:180-190`, `components/settings/keyword-settings.tsx:98-132`), nested ids `parent/child` (`lib/keyword-nesting.ts`, `keyword-settings.tsx:213-243`), drag reorder (atomic, changelog 1.9.0), rename keyword migrates messages (`renameKeyword`/`client.migrateKeyword` `lib/jmap/client.ts:1963`), tag picker lists unknown ids present on a message so they can be removed (`components/email/tag-picker.tsx:484-491`).
- What RN does: `{ id, label, color }` only (`src/stores/keywords-store.ts:9-13`); `TagSheet` lists defined tags only (`src/components/TagSheet.tsx:76-95`), so a `$label:work/clients` set by WEB can neither be seen nor removed on RN. Tag definitions are device-local (see native issue #1).
- Fix hint: show unknown `$label:*` ids found on the selected emails at the bottom of `TagSheet`; add `visibility` when the drawer tag section lands; nesting/reorder are lower priority.
+2 -2
View File
@@ -260,7 +260,7 @@ Legend for refs: WEB paths are relative to `the webmail repo`, RN paths to `the
### Security / crypto
- [ ] **S/MIME sign/encrypt on send is a stub** — `P3` — `missing` — deferred: no raw-MIME send path in RN; certificates are stored only
- [x] **S/MIME sign/encrypt on send is a stub** — `P3` — `missing` — deferred: no raw-MIME send path in RN; certificates are stored only — fixed in b0997c0a
- What WEB does: crypto plugins hook `onComposeSend` (`email-composer.tsx:2180-2216`) and the store has `sendRawEmail` (`stores/email-store.ts:1724`).
- What RN does: `src/components/settings/SmimeSettings.tsx` lists imported certificates ("Your Certificates", "Recipient Certificates") but `ComposeScreen.tsx` has no sign/encrypt control (`grep -i smime|sign|encrypt` → none) and `sendEmail` has no raw-MIME path.
- Fix hint: out of scope for parity right now; document as a known gap in the settings pane ("certificates are stored but not yet used for sending").
@@ -272,7 +272,7 @@ Legend for refs: WEB paths are relative to `the webmail repo`, RN paths to `the
- What RN does: `settings-store.ts:105-106` has `trustedSenders`, but `ComposeScreen.tsx` never touches it (`grep -i trusted` → none).
- Fix hint: after a successful reply push `finalTo`/`finalCc` emails into `trustedSenders` (dedupe).
- [ ] **Offline send is not queued** — `P3` — `missing` (RN-only opportunity) — deferred: needs a new outbox op kind carrying the whole Email/set + submission payload; drafts now autosave to the server instead — not done: offline queue is its own project; the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows
- [x] **Offline send is not queued** — `P3` — `missing` (RN-only opportunity) — deferred: needs a new outbox op kind carrying the whole Email/set + submission payload; drafts now autosave to the server instead — the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows — fixed in 0ec809eb
- What RN does: `outbox-store.ts:40-43` only knows `keywords|mailboxes|destroy` ops; `performSend` fails with a network error when offline (`ComposeScreen.tsx:975-979`) and the composed text is lost unless the user keeps the screen open. WEB has no offline outbox either, so this is not a parity item, but once drafts exist the natural mobile behaviour is "save draft locally, submit when online".
- Fix hint: add a `send` op kind carrying the Email/set create + submission payload, flushed by `outbox-store.flush`.
+1 -1
View File
@@ -174,7 +174,7 @@ RN has a solid read path (month/week/agenda, shared-calendar namespacing, per-vi
- What RN does: `src/i18n/index.ts` + `useLocaleStore` are used by 18 other files, but none of `src/components/calendar/*`, `src/screens/CalendarScreen.tsx` or `CalendarSettings.tsx` import it; all labels ("Today", "No events", "Does not repeat", "Going?", RSVP labels, drawer titles, etc.) and `date-fns` `format()` calls without a `locale` are English (`CalendarScreen.tsx:408, 448, 504, 640-641`, `EventModal.tsx:60-67, 326, ...`, `MonthView.tsx:25-26`, `AgendaView.tsx:33-37`).
- Fix hint: add a `calendar.*` namespace to `locales/*.json` (WEB's keys can be copied) and pass a date-fns locale from the locale store into `format()`.
- [ ] **First day of week limited to Monday/Sunday; no Saturday, no Jalali (#490)** — `P3` — `missing` — Saturday (0|1|6) done in 0f80e98; deferred: Jalali month grid needs a port of `lib/jalali-utils.ts` + `useCalendarLocale`
- [x] **First day of week limited to Monday/Sunday; no Saturday, no Jalali (#490)** — `P3` — `missing` — Saturday (0|1|6) done in 0f80e98; deferred: Jalali month grid needs a port of `lib/jalali-utils.ts` + `useCalendarLocale` — fixed in f1297b6b (Saturday kept after a restart since 10fb7ab7; Android date pickers and widgets stay Gregorian)
- What WEB does: `firstDayOfWeek` 0/1/6 with Saturday default for Persian and a full Jalali month grid / headers (ref `hooks/use-calendar-locale.ts:35-120`, `lib/jalali-utils.ts:161-169`, changelog 1.8.0 #490).
- What RN does: `FirstDayOfWeek = 0 | 1` (`src/stores/settings-store.ts:76`), `MonthView`/`WeekView` typed `0 | 1` (`MonthView.tsx:34`, `WeekView.tsx:40`), no Jalali.
- Fix hint: widen the type to `0|1|6`, add Saturday to `CalendarSettings`; Jalali is a larger port of `jalali-utils.ts` + a `useCalendarLocale` equivalent (only if the fa locale is added to RN).
+2 -2
View File
@@ -181,7 +181,7 @@ RN's JMAP client (`src/api/jmap-client.ts`, 615 lines) is a thin transport: sess
- What RN does: `android:allowBackup="true"` with `@xml/secure_store_backup_rules` from the expo-secure-store plugin, which only excludes SecureStore's own prefs (`android/app/src/main/AndroidManifest.xml:16`); the AsyncStorage SQLite DB (full cached bodies `webmail:offline-cache:entry:v2:*`, outbox, settings, account registry) is backed up to the user's Google account.
- Fix hint: add an app-owned `fullBackupContent`/`dataExtractionRules` excluding `databases/RKStorage` (AsyncStorage) or set `allowBackup=false` via an Expo config plugin.
- [ ] **Send has no offline path and no draft fallback** — `P2` — `missing` — partly: drafts autosave to the server since 5b72c4d, and since 92b42e4 the close dialog no longer drops the text when the draft can't be saved; an offline send is still not queued, and a draft can't be saved offline — not done: offline queue is its own project; the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows
- [x] **Send has no offline path and no draft fallback** — `P2` — `missing` — partly: drafts autosave to the server since 5b72c4d, and since 92b42e4 the close dialog no longer drops the text when the draft can't be saved; a draft can't be saved offline — the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows — fixed in 0ec809eb
- What WEB does: no offline queue either, but send failures leave the composer open with the draft autosaved (composer agent's area); send itself has a deadline (#702).
- What RN does: `ComposeScreen` shows `Alert('Send failed')` and keeps the modal (`src/screens/ComposeScreen.tsx:975-979`); there is no draft API in `src/api/email.ts` (`grep -n '[Dd]raft' src/api/email.ts` only finds the send create id), so the body is lost if the user leaves, and an offline send is not queued although the outbox exists.
- Fix hint: either add an `outbox` `send` op kind (blob uploads must already be done) or at minimum persist the composer state locally on failure.
@@ -231,7 +231,7 @@ RN's JMAP client (`src/api/jmap-client.ts`, 615 lines) is a thin transport: sess
- What RN does: `onShouldStartLoadWithRequest` returns `true` for any `data:` URL (`src/components/EmailBodyView.tsx:715-718`), so `<a href="data:text/html,...">` replaces the message with attacker HTML rendered inside the app chrome (phishing form); the WebView is otherwise well hardened (`originWhitelist=['about:blank']`, file access off, `mixedContentMode="never"`, `setSupportMultipleWindows={false}`, `incognito`, `domStorageEnabled={false}`, `EmailBodyView.tsx:675-712`).
- Fix hint: allow `data:` only for `request.isTopFrame === false` or block it entirely (the body is loaded via `source={{html}}`, not a data: URL).
- [ ] **No screenshot / recent-apps protection option** — `P3` — `missing` — not done: needs a new native module (expo-screen-capture)
- [x] **No screenshot / recent-apps protection option** — `P3` — `missing` — fixed in 0ae33f3a (the Android 14 launch crash it caused in d2d44e0d)
- What WEB does: N/A.
- What RN does: no `FLAG_SECURE`/`expo-screen-capture` anywhere; mail content appears in the Android recents thumbnail.
- Fix hint: optional "Hide content in app switcher" setting using `expo-screen-capture` `preventScreenCaptureAsync`.
+12 -12
View File
@@ -38,7 +38,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- What RN does: trusts the count (up to 2^32) and loops on non-advancing reads (`src/lib/tnef.ts:201`, `:211`).
- Fix hint: clamp to remaining/4, break on a null or non-advancing read.
- [ ] **Webmail hand-off returns the password in the `bulwarkmobile://` fragment** — `P2` — `bug` (cross-repo)
- [x] **Webmail hand-off returns the password in the `bulwarkmobile://` fragment** — `P2` — `bug` (cross-repo) — fixed in ab2e5a60 (webmail side fb3ba0275)
- What WEB does: `app/(main)/[locale]/login/page.tsx:426`, `lib/auth/mobile-handoff.ts:31` put the password in the redirect.
- What RN does: reads it from the fragment (`src/lib/oauth.ts:247`); any app can claim a custom scheme.
- Fix hint: hand back a one-time code and redeem it like QR pairing (`src/lib/oauth.ts:435`, `/api/auth/pair/redeem`). Needs the webmail side first.
@@ -50,7 +50,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
### Accounts and sign-in
- [ ] **Org user policy and "Set by your organisation"** — `P2` — `missing` (blocked)
- [ ] **Org user policy and "Set by your organisation"** — `P2` — `missing` (blocked) — partly: applied in 9d977773, locked and hidden settings in f27e2ceb, colour mode in b7b3dd4c, archiving off in efb92593 and 13dcbdc0, delegates and recovery in bc47c6a1; not yet: share rights for mail folder presets, group-identity scopes, Archive on the Android widget
- What WEB does: locks or hides settings per domain or group (`stores/policy-store.ts:110`, `hooks/use-restriction.ts:22`, `components/settings/org-locked-note.tsx:14`), incl. colour mode #1280, archiving off #1257, tags above shared mailboxes #1334, share rights, hiding delegates or recovery.
- What RN does: nothing (`src/stores/settings-store.ts:453`); the paired webmail is forgotten (`src/lib/oauth.ts:292`).
- Fix hint: keep the webmail URL at hand-off/pairing and fetch the policy with a bearer token. Needs a webmail route that accepts a JMAP bearer token. See "Needs a decision".
@@ -74,7 +74,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- What WEB does: `lib/idn.ts:25` (#1100). What RN does: ASCII-only checks (`src/lib/recipients.ts:31`, `src/lib/server-discovery.ts:78`).
- Fix hint: toASCII on the wire, Unicode on screen.
- [ ] **Sign-out doesn't end the identity provider session** — `P3` — `missing` — not done: needs a decision; the app keeps the shared browser session for a first sign-in on purpose, an ephemeral session helps on iOS only, and end_session needs the id_token the app does not keep plus a registered post-logout redirect
- [x] **Sign-out doesn't end the identity provider session** — `P3` — `missing` — fixed in 5a301d62
- What WEB does: `app/api/auth/token/route.ts:90` (#905). What RN does: `src/lib/oauth.ts:219`, `src/lib/oauth-native.ts:158`.
- Fix hint: open end_session_endpoint, or use an ephemeral browser session.
@@ -155,7 +155,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [x] **Search folder picker is flat and capped at 12** — `P3` — `partial` — fixed in e5c9433a
- What WEB does: `lib/search-scope-folders.ts`. What RN does: `src/screens/EmailListScreen.tsx:1729-1740` (`slice(0, 12)`).
- [ ] **Tags without a definition are grey; no account tint (#1052); tag visibility, nesting, order** — `P3` — `partial`
- [ ] **Tags without a definition are grey; no account tint (#1052); tag visibility, nesting, order** — `P3` — `partial` — partly: nesting and visibility in 585c70a5; grey undefined tags, account tint and order still open
- What WEB does: `hooks/use-keyword-format.ts`, `stores/settings-store.ts:391`. What RN does: `src/screens/EmailListScreen.tsx:164`, `src/stores/keywords-store.ts:9`.
- [ ] **Today/yesterday follow the time zone setting (#1259); .eml import and cross-account moves keep the date (#891)** — `P3` — `partial`
@@ -198,7 +198,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [x] **Part names that are paths (#1371, #1373)** — `P3` — `bug` — fixed in 4d545f8f
- What WEB does: `lib/jmap/download-name.ts:11`. What RN does: `src/api/jmap-client.ts:1350` puts `%2F` into the download URL.
- [ ] **Dark mode recolours instead of inverting** — `P3` — `missing`
- [x] **Dark mode recolours instead of inverting** — `P3` — `missing` — fixed in 23b2bf97
- What WEB does: `lib/email-dark-mode.ts:48`, `:71`. What RN does: `filter: invert(1) hue-rotate(180deg)` (`src/lib/email-html.ts:500`); mail's own dark styles follow the system scheme (`:640`).
- [x] **"via" badge repeats the sender's address** — `P3` — `bug` — fixed in fac54b41
@@ -249,7 +249,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- What WEB does: `lib/outgoing/external-recipients.ts:53`, `:107`, `components/email/external-recipient-confirm.tsx`.
- What RN does: nothing (`src/screens/ComposeScreen.tsx:2151`, `src/components/email/QuickReplyBox.tsx`, `src/components/calendar/EventModal.tsx`).
- [ ] **Org signature with user details; legal disclaimer on every sent message** — `P2` — `missing` (blocked on the policy)
- [ ] **Org signature with user details; legal disclaimer on every sent message** — `P2` — `missing` (blocked on the policy) — partly: org signature and disclaimer in fe3f860e; the user details (title, department, phone) stay empty without settings sync
- What WEB does: added in the client before sending (`lib/org/outgoing.ts:73`, `:99`, `lib/org-signature.ts:311`, 0154e24ff).
- What RN does: mail from the phone goes out without the disclaimer (`src/screens/ComposeScreen.tsx:2151`, `src/lib/signature-utils.ts`).
@@ -267,7 +267,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [x] **Composer prompts: missing-subject asks again, autosaved draft says "unsaved", no Discard for a reopened draft** — `P3` — `bug` — fixed in 1cc4ccca
- What WEB does: `components/email/email-composer.tsx:3251`, `:3770`, `:3758`. What RN does: `src/screens/ComposeScreen.tsx:1983`, `:2135`, `:1501`, `:1454-1471`.
- [ ] **Offline send shows a raw network error; no offline send queue** — `P3` — `partial` (old 04/09 item) — not done: offline queue is its own project; the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows
- [x] **Offline send shows a raw network error; no offline send queue** — `P3` — `partial` (old 04/09 item) — the offline message (says offline, the text stays) is in a43b55ec. One verdict for the 04, 09 and 10 rows — fixed in 0ec809eb
- What WEB does: says offline and keeps the message (`components/email/email-composer.tsx:3661`). What RN does: `src/screens/ComposeScreen.tsx:2236`, `src/lib/send-failure-message.ts:57`, `src/stores/outbox-store.ts:53`.
- [x] **Scheduled time shows a minute early; presets (tomorrow 13:00, next Monday 08:00)** — `P3` — `bug`/`partial` — fixed in 8fe5798b
@@ -276,7 +276,7 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [x] **Reply puts no cursor in the body; autofill offered in address fields** — `P3` — `missing` — fixed in 8bb7b607 (composer; ParticipantInput in the event editor is the calendar pass)
- What WEB does: `components/email/email-composer.tsx:2885`. What RN does: `src/screens/ComposeScreen.tsx:2466`, `:2316`, `:2946`, `src/components/calendar/ParticipantInput.tsx:119`.
- [ ] **Composer extras: priority (#970), numeric date placeholders (#1284), @mentions (#1134), directory lookup (#1253), font size, pasted lists, DSN/REQUIRETLS** — `P3` — `missing`
- [ ] **Composer extras: priority (#970), numeric date placeholders (#1284), @mentions (#1134), directory lookup (#1253), font size, pasted lists, DSN/REQUIRETLS** — `P3` — `missing` — partly: priority and DSN/REQUIRETLS in 649d3adc, @mentions in 8389db8f, directory lookup in a7a37573; numeric date placeholders, font size and pasted lists still missing
- What WEB does: `lib/recipient-mentions.ts`, `components/email/plain-text-paste.ts`, `components/email/rich-text-editor.tsx:445`, `lib/jmap/client.ts:1392-1413`. What RN does: `src/lib/template-utils.ts:9-15`, `src/components/RichTextEditor.tsx:26`, `src/lib/editor-html.ts`.
- [x] **The recipient splitter treats an escaped quote as closing** — `P3` — `bug` — fixed in ae2eb46b
@@ -323,10 +323,10 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [x] **Moving a task into or within a shared calendar (#1204)** — `P3` — `partial` — fixed in b6995bb6
- What WEB does: `lib/jmap/client.ts:9473`. What RN does: updateTask sends unmapped calendarIds (`src/stores/calendar-store.ts:1311-1315`).
- [x] **Working hours (#1164); week all-day area (#1122); light tinted colours; Jalali; birthday colour; copy title/append note; component set on new calendars (#760); date deep links; background reminder refresh without device sync** — `P3` — `missing`/`partial` — birthday colour fixed in 574db426, copy title/append note in baa3ff59 (duplicate and .ics export were there), week all-day area in 90ce7c1b (sized from the days in view, tasks under their day's events, three rows with +N), light tinted colours in 01578ac2 (Settings > Calendar "Light event colors"), date deep links in fe455370 (`/calendar/<view>/<date>`, a bare date keeps the view, `tasks` opens the task list); left: background reminder refresh without device sync: left, it needs native work: the push subscription would have to carry `CalendarEvent`/`Calendar` for every account (src/lib/push-notifications.ts), PushRouting.kt would have to start a headless JS task for a calendar-only push (today it starts nothing without device sync), and that task would need a reminder scheduler that runs without the restored session and stores the in-app one (src/lib/calendar-notifications.ts) depends on; Android only, and not testable without a device. While the app runs, reminders are rescheduled on every calendar change already; working hours and Jalali: own feature, not in this run; component set (#760): needs a CalDAV client (05 row)
- [x] **Working hours (#1164); week all-day area (#1122); light tinted colours; Jalali; birthday colour; copy title/append note; component set on new calendars (#760); date deep links; background reminder refresh without device sync** — `P3` — `missing`/`partial` — birthday colour fixed in 574db426, copy title/append note in baa3ff59 (duplicate and .ics export were there), week all-day area in 90ce7c1b (sized from the days in view, tasks under their day's events, three rows with +N), light tinted colours in 01578ac2 (Settings > Calendar "Light event colors"), date deep links in fe455370 (`/calendar/<view>/<date>`, a bare date keeps the view, `tasks` opens the task list); left: background reminder refresh without device sync: left, it needs native work: the push subscription would have to carry `CalendarEvent`/`Calendar` for every account (src/lib/push-notifications.ts), PushRouting.kt would have to start a headless JS task for a calendar-only push (today it starts nothing without device sync), and that task would need a reminder scheduler that runs without the restored session and stores the in-app one (src/lib/calendar-notifications.ts) depends on; Android only, and not testable without a device. While the app runs, reminders are rescheduled on every calendar change already; Jalali in f1297b6b; working hours: own feature, not in this run; component set (#760): needs a CalDAV client (05 row)
- What RN does: `src/components/calendar/WeekView.tsx`, `src/components/calendar/TimeGridScrollView.tsx:177-185`, `src/lib/birthday-calendar.ts:6`, `src/components/calendar/EventDetailSheet.tsx:422`, `src/api/calendar.ts:1150`, `src/navigation/linking.ts:151`, `:288-299`, `src/lib/push-notifications.ts:243`.
- [ ] **Free/busy, CalendarEventNotification, organizer from ParticipantIdentity (1.10.0)** — `P3` — `missing` — not done: own feature, not in this run
- [ ] **Free/busy, CalendarEventNotification, organizer from ParticipantIdentity (1.10.0)** — `P3` — `missing` — partly: free/busy in e6a89ad0, CalendarEventNotification in d663a5e2; the organizer from ParticipantIdentity is not ported
- What WEB does: `lib/jmap/client.ts:1198`.
### Contacts
@@ -428,10 +428,10 @@ Stalwart 1.0.0 items found in the same pass (1.0 SSO scopes, Files on 1.0, #1385
- [ ] **Push extras: Inbox-only switch (#983), one ring per message (#1141), generic notification when the lookup fails (#1041), re-check on return (#1148)** — `P3` — `missing`/`partial` — Inbox-only done in 1821fda7, generic notification in f6e6f8f5, re-check on return in 327b2cae; not done: one ring per message (#1141) needs a change in the Android notification builder (BulwarkFcmModule.kt) and a device
- What RN does: `src/lib/notification-mutes.ts`, `src/lib/push-background-task.ts:468-488`, `:518`, `src/components/settings/NotificationSettings.tsx:115-134`.
- [ ] **Settings extras: language search, date locale override, font size everywhere, nav-bar icon style, sidebar apps never rendered, screenshot protection, Flat fields theme** — `P3` — `missing`/`partial` (old 08/09 items) — screenshot protection not done: needs a new native module (expo-screen-capture); text size widened in c9b3bdfe
- [ ] **Settings extras: language search, date locale override, font size everywhere, nav-bar icon style, sidebar apps never rendered, screenshot protection, Flat fields theme** — `P3` — `missing`/`partial` (old 08/09 items) — screenshot protection in 0ae33f3a; text size widened in c9b3bdfe
- What RN does: `src/components/settings/LanguageSettings.tsx:87`, `src/theme/dynamic.ts:48`, `src/lib/sidebar-apps.ts:10`, `src/theme/builtin-themes.ts:18`.
- [x] **Search snippets, size filter, mail folder sharing, global search (1.10.0)** — `P3` — `missing` — search snippets fixed in 1342e2a0, size filter in aac8a403 (live checks on 0.16 and 1.0 in 12b798c0); not done: mail folder sharing and global search, own feature, not in this run
- [x] **Search snippets, size filter, mail folder sharing, global search (1.10.0)** — `P3` — `missing` — search snippets fixed in 1342e2a0, size filter in aac8a403 (live checks on 0.16 and 1.0 in 12b798c0); mail folder sharing in 417f1843 (the admin's share rights don't hide the write presets yet), global search in f15b7bb3 (other logins' file listing capped at about 500 items; the Pro search tab and saved searches not ported)
## Old open items (docs/parity 01-09, audit-2026-09)
Of 42 open boxes and "Missing vs webmail" items, 8 are done (84fef142 calendar UI strings, f62849d1 iOS push, 75299244 Tabler icons, 26a34d59 autocomplete groups, 5802cae contact deep link, status bar theming, birthday time zone, folder colours 548b647), 9 are no longer relevant (identity and template sync, settings sync, S/MIME is a plugin, #379 migration, stability banner, admin relay list, Android badge is iOS-only by design), and 25 are still open; those are folded into the rows above.
+6 -6
View File
@@ -44,7 +44,7 @@ Classification: `bug` = fixed in the webmail, still live in the app; `missing`;
- What RN does: none. The app reads reduce motion (`src/theme/dynamic.ts:92`) but doesn't pass it into mail.
- Fix hint: pass reduce motion into the body CSS (animation off, GIFs paused) first; read aloud and reader view are left to the OS.
- [ ] **No BIMI sender logos or verified-mark check** — `P3` — `missing`
- [ ] **No BIMI sender logos or verified-mark check** — `P3` — `missing` — partly: BIMI logos from the webmail in 83ddd137 (list, unified inbox and reader in 6b7e752c); no check mark for a verified mark
- What WEB does: when DMARC passes for the exact From domain the avatar shows the domain's BIMI logo before the favicon, with a check mark when a VMC/CMC backs it; DNS and certificate checks run on the webmail server (`lib/email-headers.ts:175`, `components/ui/avatar.tsx:292`, `app/api/bimi/route.ts:49`). cf0eb03c4.
- What RN does: contact photo, DuckDuckGo favicon, initials (`src/components/SenderAvatar.tsx:38`, `:62-65`; `src/lib/avatar-utils.ts:149`).
- Fix hint: use the paired webmail's `/api/bimi` once the app keeps the webmail URL (same blocker as the org policy, file 10).
@@ -155,12 +155,12 @@ Classification: `bug` = fixed in the webmail, still live in the app; `missing`;
- What RN does: month day cells read only the number and the dots are silent (`src/components/calendar/MonthView.tsx:199-240`); event blocks have no role, label or date (`src/components/calendar/EventBlock.tsx:72-104`).
- Fix hint: label day cells with date and event count; event blocks get a button role and a label with title, date and time.
- [ ] **No reading fonts, text spacing, more contrast or underlined links** — `P3` — `missing` — not done: own feature, not in this run
- [ ] **No reading fonts, text spacing, more contrast or underlined links** — `P3` — `missing` — partly: reading fonts in 4724c28f (iOS in cfca6b9c, untested on a device); text spacing, more contrast and underlined links not done
- What WEB does: Atkinson Hyperlegible Next, Lexend, OpenDyslexic, spacing settings, more contrast, underlined links (`lib/accessibility-settings.ts:53-68`; 8008393e5, da215b8c0).
- What RN does: none of these settings (`src/stores/settings-store.ts`).
- Fix hint: the dyslexia font and line spacing first.
- [ ] **No colour-blind palette and no names next to colours** — `P3` — `missing` — not done: own feature, not in this run
- [ ] **No colour-blind palette and no names next to colours** — `P3` — `missing` — partly: colour-blind-safe palette for tags in c6501ec8 and calendars in 21dd5a24; no names next to colours
- What WEB does: a colour-blind-safe palette, a tag's letter in its dot, the calendar's name on events (cf4d02b49, d5d7d39ef, 396290003).
- What RN does: colours only (`src/components/calendar/EventBlock.tsx:72-104`, `src/components/calendar/MonthView.tsx:233-240`).
@@ -169,11 +169,11 @@ Classification: `bug` = fixed in the webmail, still live in the app; `missing`;
- What RN does: 5 s, errors 10 s (`src/stores/toast-store.ts:44`), Undo 5 s (`src/components/UndoSnackbar.tsx:15`).
- Fix hint: a duration setting and a longer default while a screen reader is on.
- [ ] **No plain language and no explanations for technical terms** — `P3` — `missing` — not done: own feature, not in this run
- [ ] **No plain language and no explanations for technical terms** — `P3` — `missing` — partly: plain language in 97b71e22; no explanations for technical terms
- What WEB does: simpler English and German wording (`i18n/plain-language.ts`; bb739c744, 9861af6be, 5ffecf692) and term explanations (`components/ui/term.tsx`; 724c45d6e).
- What RN does: none (`src/i18n/index.ts:79-140`).
- [ ] **Accessibility statement, help and sign-language links aren't shown** — `P3` — `missing`
- [x] **Accessibility statement, help and sign-language links aren't shown** — `P3` — `missing` — fixed in 9d977773
- What WEB does: shows the operator's links from the public `/api/config` (`app/api/config/route.ts:104`; 315e29270, 623c9e179).
- What RN does: About has only the app's own links (`src/lib/about-links.ts:5-28`); the webmail URL isn't kept (`src/lib/oauth-native.ts:93-108`).
- Fix hint: keep the paired webmail URL (also needed for the org policy) and read `/api/config`.
@@ -224,7 +224,7 @@ Classification: `bug` = fixed in the webmail, still live in the app; `missing`;
### Notifications
- [ ] **New mail can't play the Involved sound** — `P3` — `missing`
- [x] **New mail can't play the Involved sound** — `P3` — `missing` — fixed in 6a27c596 (calendar reminders in b4f10829)
- What WEB does: Involved by default (`stores/settings-store.ts:949`, `lib/notification-sound.ts:11`). 5eabdd890.
- What RN does: the OS channel owns the sound (`src/stores/settings-store.ts:266-267`).
- Fix hint: optional; needs a new Android channel id and a bundled iOS sound.
+1 -1
View File
@@ -407,7 +407,7 @@ carries the commit that fixed it.
with the usual "-- " delimiter and the composer adds its own separator above it (screenshot
`t_compose_panel`).
- Fix: don't add a separator to a signature that already starts with one.
- [ ] **U-069 · P2 · PL · Recipient suggestions can't show in phone landscape.** *(deferred: with the keyboard up a phone in landscape has about 100 dp left; suggestions need a different design (a full-screen picker), which is a feature)* With the keyboard
- [x] **U-069 · P2 · PL · Recipient suggestions can't show in phone landscape.** *(deferred: with the keyboard up a phone in landscape has about 100 dp left; suggestions need a different design (a full-screen picker), which is a feature)* With the keyboard — fixed in e1ad5c09
up, about 50 dp are left under the To field, so the suggestion list is hidden behind the
keyboard. Typing a full address still works.
### Calendar