Merge branch 'main' of git.arirex.me:iris/ai-app
This commit is contained in:
commit
d829a77ddf
6 files changed
+149
-259
No files matched your search
@@ -45,9 +45,7 @@ import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.layout.positionInRoot
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
@@ -142,21 +140,6 @@ private class TopEdgeHold {
|
||||
var key: Any? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Where a row is on screen, so a tap on it can be told which half it landed in.
|
||||
*
|
||||
* Not snapshot state, for the same reason as [TopEdgeHold]: written from layout, read from a click,
|
||||
* and observed by nothing.
|
||||
*/
|
||||
private class RowBounds {
|
||||
var top = 0f
|
||||
var height = 0f
|
||||
|
||||
/** Above this is the row's top half, below it the bottom half. */
|
||||
val middle
|
||||
get() = top + height / 2
|
||||
}
|
||||
|
||||
/** One row's height between layouts, so a change in it can be noticed. See [holdTopEdge]. */
|
||||
private class LastHeight {
|
||||
var value: Int? = null
|
||||
@@ -643,10 +626,6 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
// by default, which is the rule for anything new in this transcript: a screen that opens
|
||||
// everything it can is one nobody can scan.
|
||||
var expandedNotes by remember { mutableStateOf(setOf<Long>()) }
|
||||
// Long replies the reader has asked to see the rest of, by the seq of the row. Held here
|
||||
// rather than in the row so that scrolling away and back does not shut something they
|
||||
// deliberately opened -- the same reason the sets above it are here.
|
||||
var expandedReplies by remember { mutableStateOf(setOf<Long>()) }
|
||||
// Uploaded-but-not-yet-sent attachment ids; sent with the next message.
|
||||
var pendingAttachments by remember { mutableStateOf(listOf<String>()) }
|
||||
// What this session is set to now, seeded from the row that opened it and
|
||||
@@ -714,12 +693,6 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
// What is actually drawn: the transcript with runs of adjacent tool
|
||||
// calls folded into one row each.
|
||||
val rows = remember(items) { groupToolRuns(items) }
|
||||
// The reply drawn whole however long it is; see the transcript list below. Recomputed with
|
||||
// `items` rather than tracked as it arrives, because "newest" moves: a reply that was the
|
||||
// last one becomes history the moment the next turn starts, and a row that kept its
|
||||
// exemption after that would be the one enormous row this exists to bound.
|
||||
val newestReply =
|
||||
remember(items) { items.filterIsInstance<TranscriptItem.AssistantMsg>().lastOrNull()?.seq }
|
||||
|
||||
/**
|
||||
* Everything the transcript list draws, from one event.
|
||||
@@ -833,8 +806,8 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
*
|
||||
* The correction itself belongs to the measurement -- see [holdTopEdge].
|
||||
*/
|
||||
fun toggleAnchored(key: Any, row: RowBounds, at: Float, toggle: () -> Unit) {
|
||||
if (at < row.middle) topEdgeHeld.key = key
|
||||
fun toggleAnchored(row: TranscriptRow, toggle: () -> Unit) {
|
||||
if (listState.tappedHigh(row.startSeq)) topEdgeHeld.key = row.key
|
||||
toggle()
|
||||
}
|
||||
|
||||
@@ -1423,21 +1396,14 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
}
|
||||
},
|
||||
) { row ->
|
||||
val bounds = remember { RowBounds() }
|
||||
Box(
|
||||
Modifier.onGloballyPositioned {
|
||||
bounds.top = it.positionInRoot().y
|
||||
bounds.height = it.size.height.toFloat()
|
||||
}
|
||||
.holdTopEdge(row.key, topEdgeHeld) { grew -> listState.by(grew) }
|
||||
) {
|
||||
Box(Modifier.holdTopEdge(row.key, topEdgeHeld) { grew -> listState.by(grew) }) {
|
||||
when (row) {
|
||||
is TranscriptRow.Tools ->
|
||||
ToolGroup(
|
||||
group = row,
|
||||
expanded = row.id in expandedGroups,
|
||||
onToggle = { at ->
|
||||
toggleAnchored(row.key, bounds, at) {
|
||||
onToggle = {
|
||||
toggleAnchored(row) {
|
||||
expandedGroups =
|
||||
if (row.id in expandedGroups)
|
||||
expandedGroups - row.id
|
||||
@@ -1448,8 +1414,8 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
// Anchored on the group, not the call: opening one call makes
|
||||
// the whole group taller, and the heading the reader is under
|
||||
// is the group's.
|
||||
onToolToggle = { id, at ->
|
||||
toggleAnchored(row.key, bounds, at) {
|
||||
onToolToggle = { id ->
|
||||
toggleAnchored(row) {
|
||||
expandedTools =
|
||||
if (id in expandedTools) expandedTools - id
|
||||
else expandedTools + id
|
||||
@@ -1476,43 +1442,14 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
text = item.text,
|
||||
images = item.images,
|
||||
)
|
||||
is TranscriptItem.AssistantMsg -> {
|
||||
// The newest reply is never cut. It is the one being read
|
||||
// as it arrives -- often still arriving -- and putting a
|
||||
// "show the rest" under a turn somebody is waiting for
|
||||
// hides the answer they are waiting for. Every reply
|
||||
// behind it is history, and history is what this is for.
|
||||
val shortened =
|
||||
if (
|
||||
item.seq == newestReply ||
|
||||
item.seq in expandedReplies
|
||||
)
|
||||
null
|
||||
else remember(item.text) { shortenedReply(item.text) }
|
||||
if (shortened == null) {
|
||||
AssistantMessage(item.text, replies)
|
||||
} else {
|
||||
CappedReply(
|
||||
full = item.text,
|
||||
shortened = shortened,
|
||||
replies = replies,
|
||||
onShowMore = {
|
||||
// Anchored like every other row that changes
|
||||
// height, so the edge the reader touched
|
||||
// stays where it is.
|
||||
toggleAnchored(row.key, bounds, bounds.top) {
|
||||
expandedReplies = expandedReplies + item.seq
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
is TranscriptItem.AssistantMsg ->
|
||||
AssistantMessage(item.text, replies)
|
||||
is TranscriptItem.ToolRun ->
|
||||
ToolCard(
|
||||
tool = item,
|
||||
expanded = item.id in expandedTools,
|
||||
onToggle = { at ->
|
||||
toggleAnchored(row.key, bounds, at) {
|
||||
onToggle = {
|
||||
toggleAnchored(row) {
|
||||
expandedTools =
|
||||
if (item.id in expandedTools)
|
||||
expandedTools - item.id
|
||||
@@ -1566,8 +1503,8 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
|
||||
item = item,
|
||||
expanded = item.seq in expandedNotes,
|
||||
replies = replies,
|
||||
onToggle = { at ->
|
||||
toggleAnchored(row.key, bounds, at) {
|
||||
onToggle = {
|
||||
toggleAnchored(row) {
|
||||
expandedNotes =
|
||||
if (item.seq in expandedNotes)
|
||||
expandedNotes - item.seq
|
||||
|
||||
Reference in new issue
Block a user