Files
ai-app/app/androidApp/src/main/kotlin/com/example/aiapp/Dividers.kt
T
iris b172c464ea ai-app: a phone interface to Claude Code and llama.cpp sessions
A Rust backend that owns the sessions and an Android app that reads them.
The server spawns and adopts CLI processes, normalises everything they emit
into one event model, keeps the transcript, and serves it over pinned TLS on
a WireGuard interface; the phone streams that, replies, sends images, and
imports conversations the machine already has.

`AGENTS.md` is the working guide -- what runs where, what has been measured,
and the faults that were expensive to find. `PLAN.md` is the design record.

History before this point was squashed away. It was a personal project's
running commentary and carried a name and a couple of machine paths that
have no business in a public repository; the tree is what mattered and the
tree is here.
2026-08-31 20:29:07 -04:00

55 lines
2.2 KiB
Kotlin

package com.example.aiapp
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
/**
* A line across the transcript saying what left the session's context.
*
* Centred between two rules, because it is a divider rather than something anybody said. Two things
* produce one -- a compaction and a clear -- and they are drawn the same way on purpose: to a
* reader scrolling back, both mean "the session no longer has what is above this", and which of the
* two it was is said by the words and the colour.
*
* The rules take [color] too, so the whole divider reads as one mark of one kind rather than a
* coloured phrase sitting in an unrelated grey line.
*
* Written once here rather than styled at each of them, so the two cannot drift into looking like
* different kinds of thing.
*/
@Composable
fun TranscriptDivider(text: String, color: Color, modifier: Modifier = Modifier) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier.fillMaxWidth().padding(vertical = 8.dp),
) {
HorizontalDivider(Modifier.weight(1f), color = color)
Text(text, style = MaterialTheme.typography.bodySmall, color = color)
HorizontalDivider(Modifier.weight(1f), color = color)
}
}
/**
* The mark a clear leaves.
*
* Red, and no counts: a clear takes the conversation out of what the session is given, and unlike a
* compaction it summarises nothing and measures nothing, so there is nothing to report but the
* fact. Everything above stays on screen and stays scrollable -- the reader can see that, which is
* why this does not say it.
*/
@Composable
fun ClearedRow(modifier: Modifier = Modifier) {
TranscriptDivider("Context cleared", clearedColor, modifier)
}