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
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user