Let the reader put the session list in its own order
Nothing sorts the sessions tab any more. The order is the server's `sessions` list, which is the reader's arrangement: holding a row puts the screen in selection mode -- the same gesture and the same bottom bar as the import tab -- and each card grows a burger handle at its right edge that drags the row to a new place, with a tick of haptic feedback for each one it passes. The two attempts this replaces, sorting by activity and then by when each agent was turned on, were both looking for an order a session could not move itself out of; no rule computed from what a session is doing can be one. `POST /sessions/order` rewrites the config's order, so it is the same on every device and survives a backend restart, and `SessionConfig::started` goes with the sort that needed it. Rearranging is independent of the selection: the handle moves the row it is on, picked out or not. The click moved off the card and onto its contents so that a press landing on the handle cannot also select the row it is about to move. Selection's one action is Delete, which now takes the whole set. Two traps in `Reorder.kt`, both measured on the emulator and written down in `this-machine-android`: a crossing is decided from how far the finger has travelled, because a lazy list animates an item into its new place and its `offset` reports the old one for several frames; and the viewport is pinned with `requestScrollToItem` around each move, because a lazy list keeps its place by the key of the top item and would otherwise follow the row being dragged. Verified on the emulator against the sandbox: the order survives an app restart and a backend read-back, a two-row drag moves exactly two rows, a drag to the bottom edge scrolls the list and lands the row last, pressing the handle without moving changes nothing, and deleting two selected sessions leaves the rest in place.
This commit is contained in:
1 parent
942edd6b31
commit
b7fd18b195
12 files changed
+801
-339
No files matched your search
@@ -1428,22 +1428,34 @@ Kotlin + Compose Multiplatform, single `:androidApp` module, same versions as
|
||||
dev-updater (Kotlin 2.4.x, CMP 1.11.x, JDK 21).
|
||||
|
||||
1. **Session list** — kind icon, title, machine, model, status, last activity.
|
||||
**A session with a process stays where it is, and the order is when each
|
||||
agent was turned on** (2026-09-15, replacing the awaiting-answer inbox
|
||||
sort): the running sessions come first, oldest start first, so one that is
|
||||
started joins the bottom of that group and nothing it goes on to do —
|
||||
beginning a turn, finishing one, asking a question — can move it. A list
|
||||
that reorders itself is one nobody can keep their place in, and the status
|
||||
word and its colour already say which session wants an answer without the
|
||||
row having to move to say it. Stopped sessions are a group below, most
|
||||
recently active first; "turned on" is what the order above is made of and a
|
||||
session with no process has no place in it.
|
||||
The order is the server's (`SessionConfig::started`, reported as
|
||||
`started`), written each time a process is started for the session, so it
|
||||
is the same on every device and survives a backend restart — which adopts
|
||||
processes rather than starting them, and so could not work the times out
|
||||
for itself. Applied on the phone (`sessionsInListOrder`), because
|
||||
presentation order is a display decision.
|
||||
**Nothing sorts it: the order is the reader's own** (2026-09-20,
|
||||
superseding first the awaiting-answer inbox sort and then ordering by when
|
||||
each agent was turned on). Both of those were attempts to find an order a
|
||||
session could not move itself out of, and the answer is that no rule
|
||||
computed from what a session is doing can be one — the reader is the only
|
||||
thing that knows which conversation matters. A list that rearranges itself
|
||||
is one nobody can keep their place in, and the status word and its colour
|
||||
already say which session wants an answer without the row having to move to
|
||||
say it.
|
||||
The order is the server's `sessions` list, rewritten by
|
||||
`POST /sessions/order`, so it is the same on every device and survives a
|
||||
backend restart, and a spawn appends rather than displacing anything.
|
||||
`SessionConfig::started` and the `started` field went with the sort that
|
||||
needed them.
|
||||
**Rearranging is a drag on a handle, in selection mode** — hold a row to
|
||||
enter it, the same gesture and the same bottom bar as the import tab, and
|
||||
each card grows a burger handle at its right edge. The handle rather than
|
||||
the row, because a row that can be dragged is a row that sometimes eats a
|
||||
fling; and the click is on the card's contents rather than on the card, so
|
||||
a press that lands on the handle cannot also select the row it is about to
|
||||
move. The move is applied on the phone as the finger crosses each row, with
|
||||
a tick of haptic feedback for each, and the whole order is sent when the
|
||||
finger comes up: a server asked per crossing would be answering about an
|
||||
arrangement that had already changed. A refused save puts the server's own
|
||||
order back rather than leaving the screen showing one nothing kept.
|
||||
Rearranging is deliberately independent of what is selected — the handle
|
||||
moves the row it is on — because "which rows am I acting on" and "where
|
||||
does this one go" are two questions.
|
||||
2. **Import** — Claude Code sessions the machine already has, selected in
|
||||
batches (hold to enter, tap to add), with Delete and Import along the
|
||||
bottom. Submitting clears the selection immediately and marks every chosen
|
||||
|
||||
Reference in new issue
Block a user