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

@@ -49,10 +49,9 @@ data class SessionBitmap(val bitmap: ImageBitmap?, val failed: Boolean)
/**
* Fetches (authenticated, pinned) and decodes one transcript image, remembered per ref so scrolling
* does not refetch.
*
* Shared by the transcript's images and the composer's pending attachments, because the fetch, the
* decode and the two-state answer are one block of logic that had been written twice.
* does not refetch. Shared by the transcript's images and the composer's pending attachments,
* because the fetch, the decode and the two-state answer are one block of logic that had been
* written twice.
*/
@Composable
fun rememberSessionBitmap(settings: ServerSettings, sessionId: String, ref: String): SessionBitmap {
@@ -75,15 +74,12 @@ fun rememberSessionBitmap(settings: ServerSettings, sessionId: String, ref: Stri
* An image in the transcript: a fixed-height thumbnail that opens full screen.
*
* The height is decided before the bytes arrive and never changes. An image row that grew when it
* finished loading pushed everything below it, so a transcript being read scrolled itself while
* somebody was looking at it -- and in a bottom-anchored list, images loading above the viewport
* moved the text under the reader's eyes. Reserving the final height makes loading invisible, which
* is what it should be.
* finished loading pushed everything below it, so a transcript being read scrolled itself -- and in
* a bottom-anchored list, images loading above the viewport moved the text under the reader's eyes.
*
* Four lines of body text, so a screenshot reads as an attachment beside the conversation rather
* than as a page of its own. Full size is one tap away -- but the full-size view itself is not
* here. [onOpen] hands the ref to the screen, which draws [SessionImageViewer] outside the list;
* see that function for the reason.
* than as a page of its own. The full-size view itself is not here: [onOpen] hands the ref to the
* screen, which draws [SessionImageViewer] outside the list.
*/
@Composable
fun SessionImage(
@@ -97,9 +93,8 @@ fun SessionImage(
val heightPx = with(LocalDensity.current) { height.roundToPx() }
Box(Modifier.fillMaxWidth().height(height), contentAlignment = Alignment.CenterStart) {
when (val image = bitmap) {
// Two states, not one: an image still arriving and an image that will never arrive
// look nothing alike to a reader who can do something about the second. So one gets a
// spinner in the space the picture is about to fill, and the other gets words.
// Two states, not one: an image still arriving and an image that will never arrive look
// nothing alike to a reader who can do something about the second.
null ->
if (failed) {
Text(
@@ -130,15 +125,12 @@ fun SessionImage(
* `Read` on its own is a row of one call, and the moment the next call arrives the two become a
* group -- a different composable in a different part of the tree, so everything the old subtree
* remembered goes, the dialog included. Somebody looking at a screenshot was thrown back to the
* transcript because the session made another tool call. The same happens to a row regrouped by a
* page of history landing.
* transcript because the session made another tool call.
*
* Held by the screen, none of that reaches it: what is open is a property of the screen, not of
* whichever row happened to draw the thumbnail.
* Held by the screen, none of that reaches it: what is open is a property of the screen.
*
* The cost is one fetch, since the thumbnail's decoded bitmap belongs to a row this does not go
* through. Paid deliberately rather than plumbed around: it is one request for a picture somebody
* asked to see, and the loading and unavailable states below are the same two the thumbnail draws.
* through. Paid deliberately: it is one request for a picture somebody asked to see.
*/
@Composable
fun SessionImageViewer(
@@ -157,9 +149,9 @@ fun SessionImageViewer(
contentAlignment = Alignment.Center,
) {
when (val image = bitmap) {
// Two states, not one, exactly as the thumbnail has them: still coming, and never
// coming. Stated in white because this box paints its own black behind them and a
// theme colour would be picked against a surface that is not there.
// Two states, not one, exactly as the thumbnail has them. Stated in white because
// this box paints its own black behind them and a theme colour would be picked
// against a surface that is not there.
null ->
if (failed) {
Text(
@@ -170,8 +162,7 @@ fun SessionImageViewer(
} else {
// The whole dialog is the area this picture is about to fill, so the
// spinner sits in the middle of it. White for the same reason the words
// beside it are: this box paints its own black, and a theme colour would
// be chosen against a surface that is not there.
// beside it are.
CircularProgressIndicator(color = Color.White)
}
else -> ZoomableImage(image)
@@ -185,11 +176,10 @@ fun SessionImageViewer(
*
* A square of the row's own height rather than the full width of the transcript: the height is what
* [SessionImage] reserves and the width is not known until the bytes arrive, so a full-width
* placeholder would promise a picture wider than most of them turn out to be. Square is the closest
* thing to "the size of it" that can be drawn before knowing.
* placeholder would promise a picture wider than most turn out to be.
*
* Tinted, so the reader can see that something is being kept for a picture. That is also what
* distinguishes it from the failure beside it, which is words on the ordinary surface.
* Tinted, so the reader can see that something is being kept for a picture -- which is also what
* distinguishes it from the failure beside it, words on the ordinary surface.
*/
@Composable
private fun LoadingImage(height: Dp) {
@@ -210,8 +200,8 @@ private val LOADING_SPINNER = 24.dp
* Four lines of the body style the transcript is set in.
*
* Measured from the type rather than written as a dp, so it stays four lines when the text size
* changes -- including when the reader has scaled fonts up, which is exactly when a hardcoded
* height would be wrong.
* changes -- including when the reader has scaled fonts up, which is when a hardcoded height is
* wrong.
*/
@Composable
private fun thumbnailHeight(): Dp {
@@ -226,8 +216,7 @@ private fun thumbnailHeight(): Dp {
* Nearest neighbour when the image is being enlarged, smooth when it is being shrunk.
*
* A small image blown up with interpolation turns into a blur that hides what it is -- the same
* image with hard pixel edges stays readable. Shrinking wants the opposite, so this is a decision
* per image rather than a preference set once.
* image with hard pixel edges stays readable. Shrinking wants the opposite.
*/
private fun enlargingFilter(sourceHeight: Int, drawnHeight: Int): FilterQuality =
if (sourceHeight < drawnHeight) FilterQuality.None else FilterQuality.High
@@ -237,7 +226,7 @@ private fun enlargingFilter(sourceHeight: Int, drawnHeight: Int): FilterQuality
*
* Inside a dialog rather than a screen -- see [SessionImageViewer] -- so the platform's back
* gesture returns to the transcript instead of leaving the app. It opens fitted, the whole image
* visible, which is the thing a reader wants first; zoom is theirs from there.
* visible.
*/
@Composable
private fun ZoomableImage(image: ImageBitmap) {