Read a timeout in units, share one usage answer, and let a tilde mean home
The composer's settings row is outlined bubbles opening round menus, and the message box is a TextFieldValue so anything put into it without being typed -- a draft, a share, a slash command -- leaves the cursor at the end. A tap that puts a text selection away no longer also collapses the card the text was drawn in: every open and close on the session screen goes through one guard that spends such a press on the selection. The usage bar and the usage dialog were two polls of one measurement and disagreed for up to a minute at a time; they are one feed now, and the countdown rounds up to the minute in the one place both read. A working directory typed as ~/repos/ai-app was four literal characters on the local transport and as an argument on both, so the existence check refused every home-relative path. It is checked by entering the directory now, expanded for a local spawn the way the remote shell expands it, and stored short so the phone draws what somebody would write. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2970a6cf9a
commit
32b2a4871a
16 files changed
+414
-99
No files matched your search
@@ -0,0 +1,38 @@
|
||||
package com.example.aiapp
|
||||
|
||||
/**
|
||||
* A span of milliseconds, written the way somebody reads it.
|
||||
*
|
||||
* A tool's timeout arrives as `480000`, which nobody reads as eight minutes. The rule has two
|
||||
* halves, because a short span and a long one are read for different things. Under a minute the
|
||||
* question is "roughly how long", so only the largest unit is shown and a fraction of it carries
|
||||
* the rest -- `2.5s`, `30ms`. At a minute or more the question is "how long exactly", so every unit
|
||||
* that has something in it is written out -- `5d 12h 4m`. Units that are empty are left out rather
|
||||
* than written as zero, since the labels say which is which and `5d 0h 4m` is only longer.
|
||||
*
|
||||
* Sub-second precision is dropped past a minute: nothing that takes days is measured in
|
||||
* milliseconds, and carrying them would make the common case the widest one.
|
||||
*/
|
||||
fun formatMillis(ms: Long): String {
|
||||
if (ms < 0) return "-" + formatMillis(-ms)
|
||||
if (ms < 1000) return "${ms}ms"
|
||||
if (ms < 60_000) {
|
||||
val tenths = (ms + 50) / 100
|
||||
val whole = tenths / 10
|
||||
val rest = tenths % 10
|
||||
return if (rest == 0L) "${whole}s" else "$whole.${rest}s"
|
||||
}
|
||||
val seconds = ms / 1000
|
||||
val parts =
|
||||
listOf(
|
||||
"d" to seconds / 86_400,
|
||||
"h" to seconds / 3600 % 24,
|
||||
"m" to seconds / 60 % 60,
|
||||
"s" to seconds % 60,
|
||||
)
|
||||
return parts.filter { it.second > 0 }.joinToString(" ") { "${it.second}${it.first}" }
|
||||
}
|
||||
|
||||
/** [text] as a span when it is a whole number of milliseconds, and unchanged when it is not. */
|
||||
fun formatMillisText(text: String): String =
|
||||
text.trim().toLongOrNull()?.let { formatMillis(it) } ?: text
|
||||
Reference in new issue
Block a user