Thin the app's comments

The same pass the server had, on the Kotlin side: comments restating what
the code says are gone, and the ones recording a measurement, a constraint
or an incident are kept but cut to a few lines each. 6540 comment lines to
5674, and 920 lines off the app.

Two doc comments had drifted onto the item above the one they describe --
`contextAfter`'s onto `sessionWorking` in Events.kt, and `UsageMonitor`'s
equivalent on the server was fixed in the previous commit. Each is back on
its own item, which is the only non-comment line this diff moves.

The comments are reflowed to the column limit at their own indentation:
several were written wide, and ktfmt re-wrapped them into lines holding a
single orphan word. `/tmp` script, not kept -- ktfmt is idempotent over the
result, which is the check.

Left alone deliberately: this codebase's remaining comment density is high
because the comments carry things the code cannot say -- what a null means,
what a number was measured against, which bug a guard exists for. Of the
238 one-line doc comments in the app, five were pure restatement of the
name and were removed; the rest each say something the signature does not.

ktfmtFormat, compileDebugKotlin, lintDebug and testDebugUnitTest pass;
cargo test (127), clippy --all-targets and fmt still clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-04 16:20:16 -04:00
1 parent 79682f03a7
commit edc39c7371
68 files changed
+2077 -2997

No files matched your search

@@ -33,16 +33,14 @@ import androidx.lifecycle.repeatOnLifecycle
/**
* A session wanting attention, said over the app rather than through Android's drawer.
*
* Two places can carry the same fact and only one of them is right at a time. A row in the shade is
* for somebody looking at something else: it makes a sound, it waits however long it has to, and
* acting on it means leaving whatever they were doing. Somebody with this app open needs none of
* that -- they are already here, and what a tap on the notification would have done is what a tap
* on this does. So while these are on screen the stream is delivered here instead, which is
* arranged by the collection below and nothing else; see `NotificationService.forTheScreen`.
* Two places can carry the same fact and only one is right at a time. A row in the shade is for
* somebody looking at something else: it makes a sound, it waits however long it has to, and acting
* on it means leaving whatever they were doing. Somebody with this app open needs none of that. So
* while these are on screen the stream is delivered here instead, which is arranged by the
* collection below and nothing else.
*
* A banner can go three ways, and each is somebody deciding something different: tapped, which
* opens the session; pushed off either side; or left alone, in which case it goes by itself when
* the bar across its foot runs out.
* A banner can go three ways, each somebody deciding something different: tapped, which opens the
* session; pushed off either side; or left alone, in which case it goes when the bar runs out.
*/
@Composable
fun SessionAlerts(onOpen: (SessionOpenRequest) -> Unit, modifier: Modifier = Modifier) {
@@ -58,28 +56,26 @@ fun SessionAlerts(onOpen: (SessionOpenRequest) -> Unit, modifier: Modifier = Mod
arrivals++
val alert = SessionAlert(notification, arrivals)
// One banner per session, replacing that session's own -- the same rule the
// drawer follows, and for the same reason: a session that finished and then
// asked a question is one thing to know about, the question. It keeps its
// place in the queue rather than moving to the end, because the reader may
// already be reaching for it.
// drawer follows: a session that finished and then asked a question is one
// thing to know about, the question. It keeps its place in the queue rather
// than moving to the end, because the reader may already be reaching for it.
val already = queue.indexOfFirst {
it.notification.sessionId == notification.sessionId
}
if (already >= 0) queue[already] = alert else queue.add(alert)
}
} finally {
// Leaving the app hands the job back to the drawer, so nothing arriving while it
// is away is lost. What would be lost is the truth of what is already up: these
// say a session wants somebody *now*, and one still sitting here on a return
// several minutes later is a claim nobody checked. Frozen, too -- Compose stops
// the clock with the window, so the timer that was going to retire it has been
// standing still the whole time.
// Leaving the app hands the job back to the drawer, so nothing arriving while it is
// away is lost. What would be lost is the truth of what is already up: these say a
// session wants somebody *now*, and one still sitting here on a return several
// minutes later is a claim nobody checked. Frozen, too -- Compose stops the clock
// with the window.
queue.clear()
}
}
}
// Oldest at the top, so a new one appears below the ones already being read instead of
// shoving them down the screen mid-reach.
// Oldest at the top, so a new one appears below the ones already being read instead of shoving
// them down the screen mid-reach.
Column(modifier.fillMaxWidth().padding(8.dp)) {
queue.forEach { alert ->
key(alert.arrival) {
@@ -103,9 +99,7 @@ private data class SessionAlert(val notification: SessionNotification, val arriv
* One banner: what wants attention, and how long this has left to say so.
*
* The bar and the going away are one value rather than a bar beside a timer, because two of them
* would be two accounts of the same countdown and only one can be the one that fires. What is drawn
* is therefore the thing that decides, which is the only arrangement where a bar that has emptied
* cannot be sitting under a banner that is still there.
* would be two accounts of the same countdown and only one can be the one that fires.
*/
@Composable
private fun AlertBanner(alert: SessionAlert, onOpen: () -> Unit, onGone: () -> Unit) {
@@ -135,9 +129,7 @@ private fun AlertBanner(alert: SessionAlert, onOpen: () -> Unit, onGone: () -> U
),
// Outlined, because the step it needs to make is not one this palette can make with a
// tint: the card under a banner on the session list is the same surface, so a banner
// relying on colour alone reads as one more row that happens to be in the way. The
// border is the one cue, and the elevation beside it is the platform's shadow rather
// than a second tint -- Material draws no tonal overlay over a container stated here.
// relying on colour alone reads as one more row in the way. The border is the one cue.
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp),
) {
@@ -145,8 +137,8 @@ private fun AlertBanner(alert: SessionAlert, onOpen: () -> Unit, onGone: () -> U
Text(
alert.notification.title,
style = MaterialTheme.typography.titleSmall,
// One line, cut at the tail: a session is identified by the start of its
// name, and a banner that grew with the name would move the one below it.
// One line, cut at the tail: a session is identified by the start of its name,
// and a banner that grew with the name would move the one below it.
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
@@ -163,9 +155,8 @@ private fun AlertBanner(alert: SessionAlert, onOpen: () -> Unit, onGone: () -> U
LinearProgressIndicator(
progress = { life.value },
// Blue because it is reporting how much of something is left rather than passing
// judgement on it -- the reason `progressColor` exists. Stated beside the track,
// which is the card's own colour so that the spent part reads as empty rather
// than as a second bar.
// judgement on it. Stated beside the track, which is the card's own colour so that
// the spent part reads as empty rather than as a second bar.
color = progressColor,
trackColor = MaterialTheme.colorScheme.surfaceContainerHigh,
drawStopIndicator = {},
@@ -180,7 +171,6 @@ private fun AlertBanner(alert: SessionAlert, onOpen: () -> Unit, onGone: () -> U
* How long a banner stays if nobody touches it.
*
* Long enough to read a session name and a line, short enough that a stack of them clears itself
* while somebody is still on the screen that produced them. The bar makes the number visible, so
* this is a duration the reader can watch rather than one they have to learn.
* while somebody is still on the screen that produced them. The bar makes the number visible.
*/
private const val ALERT_LIFE_MS = 6_000