Colour the composer by what its buttons do, and let the read-out breathe less

Queue is the paper plane with a clock on it (`md-send_clock`) rather than
the plain plane plus the word: the pair is now told apart by the mark, which
is what an icon is for, and the word survives as the button's accessible
name where a screen reader still needs it.

The three composer buttons take their colour from what pressing one does --
green sends now, blue sends later, red takes the running turn away -- and
Stop becomes a filled button like the other two. Outlined said it was a
qualifier on the primary action; it is a second thing you can do about the
turn, and what separates them is the colour and the mark. The fills are
named in Theme.kt with their content colour stated beside them, because a
semantic colour has to carry its own contrast: these do not change with the
surface, so nothing will rescue a foreground that stops being readable.
Worth knowing when reading that file: the action greens and reds sit next to
a `runningColor` green and a `failedColor` red, which are *states*. Nothing
in one set is pressable and nothing in the other is a state, so a reader
never has to tell them apart.

The usage read-out loses its per-machine cards. A card is a step up the
surface ladder and inside a dialog -- already a raised surface -- the step
barely rendered while costing 16dp on every side. The machine and the
service it answered for are one small quiet line instead of a heading over a
subtitle, since the numbers underneath are what somebody opened this to see.

The gaps between the bars now go *between* them rather than after each,
which is what put a band of empty dialog above Close. The rest of that band
was AlertDialog's own spacing, fixed at sizes meant for a sentence of prose
and a decision, so this is a plain Dialog with the same container colour and
corner and spacing chosen for a dense read-out.

Looked at on the emulator: green send, then blue queue beside red stop
during a `/slow 20` echo turn, and the dialog over the live session. The
account had risen to 78% by then, which showed the five-hour bar and the
header glyph going yellow on real numbers rather than forced ones.
This commit is contained in:
iris committed 2026-08-29 22:45:18 -04:00
1 parent ff39ef5cf9
commit 69ef6f068a
6 files changed
+132 -64

No files matched your search

@@ -30,7 +30,6 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
@@ -1056,10 +1055,15 @@ fun SessionScreen(
)
}
if (running) {
OutlinedButton(onClick = { act { interruptSession(settings, summary.id) } }) {
// The same filled shape as the button beside it, not an outlined one: these
// are two things you can do about the turn that is running, and weighting one
// of them as secondary said they were a primary action and its qualifier.
// What separates them is the colour and the mark, which is what they mean.
Button(
onClick = { act { interruptSession(settings, summary.id) } },
colors = actionButtonColors(stopColor),
) {
// A filled square, which is what stop has looked like since tape decks.
// Outlined beside the filled Send, so the pair still reads as one primary
// action and one secondary -- the glyphs changed, the weighting did not.
Glyph(
STOP_GLYPH,
colour = LocalContentColor.current,
@@ -1068,22 +1072,19 @@ fun SessionScreen(
}
Spacer(Modifier.width(8.dp))
}
// The paper plane alone when it means send. While a turn is in flight it keeps
// the word "Queue" beside it, because that is what sending then does -- the
// message is injected at the next tool boundary rather than starting a turn of
// its own -- and an icon that does two things while looking identical would
// promise something immediate and do something that waits. The word is also the
// button's accessible name, which is all a screen reader gets either way.
Button(onClick = { send() }) {
// The paper plane, with a clock on it while a turn is in flight: sending then
// queues the message for the next tool boundary rather than starting a turn of
// its own, and the two have to be told apart at a glance. The label says the same
// thing to a screen reader, which has nothing else to read.
Button(
onClick = { send() },
colors = actionButtonColors(if (running) queueColor else sendColor),
) {
Glyph(
SEND_GLYPH,
if (running) QUEUE_GLYPH else SEND_GLYPH,
colour = LocalContentColor.current,
modifier = Modifier.semantics { contentDescription = sendLabel(running) },
)
if (running) {
Spacer(Modifier.width(8.dp))
Text(sendLabel(running))
}
}
}
}