mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 00:06:17 +00:00
docs: record the widget checks after the fixes on Stalwart 0.16 and 1.0 #52
Adds the phase 2 and 3 results to the verification checklist: the corrections to phase 1 (two link failures were the test rig), every action and link re-run on both servers, which commit fixes which cause, the layout review and what is still open.
This commit is contained in:
@@ -153,3 +153,162 @@ widget's own Reply, card and event taps were also tapped on the launcher.
|
||||
event link opens the Calendar tab and nothing else (or, with an id that
|
||||
exists in both accounts, the wrong event). In the foreground the event
|
||||
link landed on the Inbox.
|
||||
|
||||
## Corrections to phase 1
|
||||
|
||||
- **L1 and L2 were faults of the test rig, not of the app.** `adb shell am
|
||||
start -d <url>` handed the URL to the device shell unquoted, and the shell
|
||||
cut it at the first `&`: Reply lost `&action=reply` (and `&thread=`), and
|
||||
"Send wishes" lost `&subject=`. Quoted, Reply opens the composer over the
|
||||
message and the subject arrives, cold, backgrounded and in the foreground,
|
||||
on 0.16 and 1.0.
|
||||
- **L4 is two app limits, not a widget fault.** A message link offline needs
|
||||
the message on the device: with the offline mail cache off (the default)
|
||||
a message is not kept across app starts and the reader says "Failed to
|
||||
load email". A link for the other account needs the server for the account
|
||||
switch, so offline it says "Couldn't open this".
|
||||
- **R1 had a second half.** Starting the background refresh directly (no
|
||||
timer) was not enough: fetch resolves every response through a zero-delay
|
||||
timer, and with the activity paused the first request went out and its
|
||||
answer was never read. The refresh now runs in a headless task of its own.
|
||||
|
||||
## After the fixes (phase 2)
|
||||
|
||||
Same rig. 1.0 was reached as `http://127.0.0.1:18191` through `adb
|
||||
reverse`, so its accounts (`usera@127.0.0.1`) sit next to the 0.16 ones;
|
||||
that path does not go through the emulator's network, so "offline" on 1.0
|
||||
was simulated with the proxy refusing `Email/set` (503) instead of airplane
|
||||
mode.
|
||||
|
||||
### Background actions
|
||||
|
||||
| Action | BG | COLD | OFF | ACC2 | DBL | UPD | 1.0 | Notes |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| archive | pass | pass | pass | n/a | pass | pass | pass | offline: the message comes back on the card with "Couldn't archive. Tap to try again."; the tap archives it once online |
|
||||
| trash | pass | pass | pass | n/a | pass | pass | pass | offline: "Couldn't delete. Tap to try again."; the tap moves it to Trash once online |
|
||||
| triageNext | pass | pass | pass | n/a | pass | pass | pass | local only, no server call |
|
||||
| rsvp | pass | pass | pass | pass (unit test) | not run | not run | call passes, see 1.0 below | offline: the invitation stays with "Couldn't send your answer"; the retry accepts it. DBL and UPD not run on the device: they go through the same serial lane and pending overlay as archive and the tick, and `actions.test.ts` covers both |
|
||||
| toggleTask | pass | pass | pass | pass (unit test) | pass | not run | call passes, see 1.0 below | two taps 150 ms apart send `completed` twice; offline the tick reverts with a notice naming the task, and tapping the notice once online sends one `CalendarEvent/set` and the task shows done. UPD not run on the device (see rsvp) |
|
||||
| any button | pass | pass | – | – | – | – | – | request codes unique (107 click intents, 107 codes) |
|
||||
|
||||
DBL for archive: two taps 150 ms apart still both name the message the
|
||||
drawing showed (the second is a harmless repeat); taps a second apart act on
|
||||
consecutive messages. UPD: with `Email/set` delayed 4 s, two archives 1.5 s
|
||||
apart leave the card on "5 of 5" for the whole run and nothing comes back
|
||||
(before: the first archive's refresh brought the second message back). Trash
|
||||
behaves the same: a double tap names the shown message twice, and two
|
||||
deletes 1.5 s apart with `Email/set` delayed move two different messages
|
||||
and nothing comes back.
|
||||
|
||||
### Deep links
|
||||
|
||||
| Link | FG | BG | COLD | OFF | ACC2 | 1.0 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| inbox, unified, scheduled, search, compose | pass | pass | pass | pass | n/a | pass |
|
||||
| message | pass | pass | pass | pass with the offline cache (L4) | pass | pass |
|
||||
| reply | pass | pass | pass | pass with the offline cache (L4) | pass | pass |
|
||||
| draft | pass | pass | pass | only if opened before (L4) | pass | not run (same route as message) |
|
||||
| compose with to + subject | pass | pass | pass | not run (no server involved) | n/a | pass |
|
||||
| calendar | pass | pass | pass | pass (no crash) | n/a | opens; see 1.0 below |
|
||||
| event | pass | pass | pass | opens the Calendar tab; the event needs the server | pass (switches account) | see 1.0 below |
|
||||
| contacts, settings | pass | pass | pass | pass (Vacation settings say the server does not support it while offline) | n/a | pass |
|
||||
| files | pass | pass | pass | pass (no crash; the screen shows the raw network error) | n/a | pass |
|
||||
|
||||
### Refresh
|
||||
|
||||
| Case | Result |
|
||||
|---|---|
|
||||
| Account switched in the app, then Home | pass: the widgets show the new account within a second, both directions |
|
||||
| App goes to the background | pass |
|
||||
| Cold periodic update | pass: mail, calendar, tasks, files and scheduled (`appDataAt` set) |
|
||||
| OAuth account with an expired access token, cold | pass: userb's token had expired an hour after sign-in; the cold refresh renewed it and loaded userb's inbox preview |
|
||||
|
||||
### Stalwart 1.0
|
||||
|
||||
- Mail actions and links pass: the archive race, a refused write with its
|
||||
notice and retry, trash, triage next, message and reply links cold and
|
||||
backgrounded, and the inbox, unified, scheduled, search, compose,
|
||||
calendar, contacts, files and settings links.
|
||||
- The app on main does not load calendar events or tasks from 1.0: its
|
||||
`CalendarEvent/get` asks for `recurrenceOverrides` together with
|
||||
`utcStart`/`utcEnd`, which 1.0 refuses as a whole (`invalidArguments`).
|
||||
The unmerged `feat/stalwart-1.0` branch fixes that. Until it is merged the
|
||||
calendar and task widgets are empty against 1.0. The widgets' own calls
|
||||
were sent to 1.0 directly: the task update (`progress`,
|
||||
`percentComplete`) and the RSVP patch both come back `updated`.
|
||||
|
||||
### Causes and their fixes
|
||||
|
||||
| Cause | Commit |
|
||||
|---|---|
|
||||
| A0 dead buttons (shared request codes) | `fix: stop widget buttons from going dead when two are drawn in the same millisecond` |
|
||||
| A3 refresh brings an archived message back, lost concurrent edits, out-of-order redraws | `fix: keep a widget archive when a second tap's refresh lands before it` |
|
||||
| A1, A5 failures looked like success, no feedback | the commit above (a failed op is dropped) and `feat: show on the widget when an action could not reach the server` |
|
||||
| A2, A4 tick flips back, item of another account | `fix: send widget RSVPs and task ticks to the item the tap was made on` |
|
||||
| A6 22dp tick | `fix: make widget task ticks easy to hit` |
|
||||
| R1 no refresh on leaving the app | `fix: refresh the widgets when the app goes to the background`, `fix: finish the widget refresh after leaving the app` |
|
||||
| R2 cold refresh skipped calendar and tasks | `fix: load calendar and tasks into the widgets when the app is not running` |
|
||||
| L3 offline crash from calendar and files widgets | `fix: keep the app from closing when a calendar widget opens it offline`, `fix: keep the app from closing when a files widget opens it offline` |
|
||||
| L5 event links without account | `fix: open a widget's event in the account it belongs to` |
|
||||
|
||||
## Phase 3: layout review
|
||||
|
||||
All 32 widgets were drawn through a temporary in-app gallery
|
||||
(`WidgetPreview`, removed again) at their smallest, default and largest
|
||||
(4x5) size with sample data, light and dark, German, very long names and
|
||||
counts (five-digit counts, 50-character names and subjects), empty data,
|
||||
and the loading, signed-out, not-yet-loaded and unsupported states, and
|
||||
with the tap areas highlighted. Fixed:
|
||||
|
||||
- The Inbox header at two cells pushed the compose button off; header
|
||||
titles now give way to the buttons, and the search icon goes at that
|
||||
width.
|
||||
- A long sender pushed the triage card's time and position out.
|
||||
- German labels were cut on the triage buttons ("Archivie", "Lösc"); they
|
||||
drop to icons when they do not fit.
|
||||
- Five-digit counts overflowed Unread count, Tag and Mail and next, and the
|
||||
total wrapped a character per line; counts from 10,000 are shortened.
|
||||
- "ungelesen" was cut in Mail and next; it moves under the number.
|
||||
- Buttons under 48dp (32–36dp) get a transparent 48dp tap area.
|
||||
- The Month arrows and the Vacation switch looked like controls but only
|
||||
opened the app.
|
||||
- Folder counts with no folders showed a bare heading.
|
||||
- A finished task past its due date read "Overdue".
|
||||
- The triage card and Latest message did not use their height for the
|
||||
preview.
|
||||
- A failure notice about a long task title cut off "Tap to try again".
|
||||
- Widget strings were English in every language; German added.
|
||||
- Avatars showed initials only, worked out differently from the webmail.
|
||||
Initials now follow the webmail everywhere in the app (first letters of
|
||||
the first and last name, leading punctuation and emoji skipped), and the
|
||||
widget avatars show the contact photo or the sender's logo first, as the
|
||||
app's list does. Logos come from the same favicon service, are fetched
|
||||
when the snapshot is built and are cached for offline drawing; a logo
|
||||
over 40 KB, or one Android cannot decode, leaves the initials.
|
||||
- The corners were rounder (22dp) than the launcher's own widgets; they are
|
||||
16dp now, previews included.
|
||||
|
||||
Checked and left as they are:
|
||||
|
||||
- Dark theme: no white fallbacks; the primary is white as in the webmail.
|
||||
- Large sizes of the 2x2 widgets are mostly empty space. A resize limit
|
||||
(`maxResizeWidth`) is given in dp, and on launchers with large cells it
|
||||
would pin a widget below two cells, so there is none.
|
||||
- RTL is not supported: the widget library does not mirror layouts, and
|
||||
there are no right-to-left widget strings.
|
||||
- Mail and next's chip for the following event is 24dp tall; the whole
|
||||
column also opens the calendar.
|
||||
|
||||
## Open
|
||||
|
||||
- A0 cannot be shown on this emulator, where each registration takes
|
||||
3–10 ms; the fix is checked by the request codes being unique.
|
||||
- Calendar and task widgets against Stalwart 1.0 wait for
|
||||
`feat/stalwart-1.0` (see above).
|
||||
- Offline message links need the offline cache; links for the other account
|
||||
need the server for the switch (L4).
|
||||
- Widget strings exist in English and German only.
|
||||
- RSVP double tap and update race, and the tick's update race, were not run
|
||||
on the device; unit tests cover them.
|
||||
- The Files screen opened offline shows the raw network error instead of an
|
||||
offline message (app screen, not a widget).
|
||||
|
||||
Reference in New Issue
Block a user