Wrap table cells instead of cutting them off, and hand a batch over in one request
The renderer draws every table cell at one line with an ellipsis, so most
of a table was unreadable on a phone -- and an elided cell looks exactly
like a short one, so nothing said anything had been cut. Cells now take as
many lines as they need and align to the top of the row. Width is the other
half: a column narrows to 136dp and no further, and past that the table
scrolls sideways rather than squeezing. 136 is the widest floor that still
fits three columns across a phone, measured rather than picked; four and up
scroll, which is the right answer for genuinely too many columns.
The import screen used to send one request per selected row, so a handover
was only as atomic as the network: some rows started and the rest were
never asked for, and a row nobody asked for looks exactly like a row nobody
picked. `POST /setups/{id}/importable/delete` and `.../import` now take the
whole list, and every id is registered as in flight before the 202 goes
back. Only the registering is atomic -- the work settles per row, since six
deletes that all roll back together is not something a filesystem offers.
The echo driver grows `/table N`, with cells long enough to have been
truncated: a fixture of tidy one-word values renders fine whether or not
the bug is there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3c159fa1e1
commit
778b2e3b04
7 files changed
+336
-93
No files matched your search
@@ -207,13 +207,22 @@ first if a remote spawn ever mangles an argument.
|
||||
and says which operation in a word** -- `BusyItem`, used by both the
|
||||
session list and the import list so the appearance is learned once. The
|
||||
word rather than a bare spinner because "deleting" and "importing" differ
|
||||
in kind, and the inertness is the overlay consuming pointer events rather
|
||||
than each caller remembering to disable its own click handler.
|
||||
- **Importing and deleting run on the server, not in the request.** `DELETE
|
||||
/setups/{id}/importable/{session}` and `POST
|
||||
/setups/{id}/importable/{session}/import` both answer 202 and do the work
|
||||
in a spawned task, because the phone that asked is free to leave and used
|
||||
to cancel its own batch by doing so. What replaces the reply is
|
||||
in kind. It dims and desaturates but does **not** make the row inert: the
|
||||
caller disables its own click handler while it passes a label. An overlay
|
||||
consuming pointer events was tried and swallowed the drag along with the
|
||||
tap, so a list could not be scrolled while anything in it was busy.
|
||||
- **Importing and deleting run on the server, not in the request, and a
|
||||
batch is handed over in one call.** `POST
|
||||
/setups/{id}/importable/delete` and `POST /setups/{id}/importable/import`
|
||||
each take a list of session ids, answer 202, and do the work in spawned
|
||||
tasks -- because the phone that asked is free to leave and used to cancel
|
||||
its own batch by doing so. A list rather than a route per session because
|
||||
one request per row made a handover only as atomic as the network: some
|
||||
rows started and the rest were never asked for, and a row nobody asked
|
||||
for looks exactly like a row nobody picked. Every id is registered as in
|
||||
flight before the 202 goes back. Only the *registering* is atomic; the
|
||||
work itself settles per row, since six deletes that all roll back
|
||||
together is not something a filesystem offers. What replaces the reply is
|
||||
`session::pending`: every row of the listing carries `pending` and
|
||||
`error`, and `GET /setups/{id}/importable/events` streams the changes.
|
||||
**Both, not either.** The stream is a broadcast with no memory, so an
|
||||
@@ -246,6 +255,20 @@ first if a remote spawn ever mangles an argument.
|
||||
be there to import again" is exactly the one the switch makes false. The
|
||||
server deletes the machine's copy *first*, so a machine it cannot reach
|
||||
leaves the session where it was instead of half-deleted.
|
||||
- **A markdown table wraps its cells and never cuts one off.** The
|
||||
renderer's own defaults draw every cell at one line with an ellipsis,
|
||||
which on a phone loses most of a table -- and an elided cell looks
|
||||
exactly like a short one, so nothing on screen says anything was cut.
|
||||
`Markdown.kt` supplies its own header and row blocks with `maxLines =
|
||||
Int.MAX_VALUE` and `TextOverflow.Clip`, cells aligned to the top of the
|
||||
row so a two-line cell does not re-centre its neighbours. Width is the
|
||||
other half: a column narrows to 136dp and no further, and past that the
|
||||
whole table scrolls sideways rather than squeezing -- 136 because it is
|
||||
the widest floor that still fits three columns across a phone, which is
|
||||
the commonest table there is. Exercise it with the echo driver's
|
||||
`/table N` (default six columns), which writes long cells on purpose:
|
||||
a fixture of tidy one-word values renders fine whether or not the
|
||||
truncation is fixed.
|
||||
- **Android Lint is not optional and is not run by a build.** It found a
|
||||
crash that had been shipping: `java.time` on a minSdk-24 app with
|
||||
desugaring off — and later a permission check that silently dropped every
|
||||
|
||||
Reference in new issue
Block a user