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:
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
|
||||
Reference in new issue
Block a user