refactor: centralize resize logic for message parts in OpenTUI session

This commit is contained in:
Dax Raad
2025-09-20 19:06:19 -04:00
parent 04c8aa1d7c
commit e107f0c341
@@ -26,7 +26,6 @@ import type { PatchTool } from "../../../tool/patch"
import type { WebFetchTool } from "../../../tool/webfetch" import type { WebFetchTool } from "../../../tool/webfetch"
import type { TaskTool } from "../../../tool/task" import type { TaskTool } from "../../../tool/task"
import { useKeyboard, type BoxProps, type JSX } from "@opentui/solid" import { useKeyboard, type BoxProps, type JSX } from "@opentui/solid"
import { createStore } from "solid-js/store"
export function Session() { export function Session() {
const route = useRouteData("session") const route = useRouteData("session")
@@ -132,28 +131,9 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[] }) {
<For each={props.parts}> <For each={props.parts}>
{(part) => { {(part) => {
const component = createMemo(() => PART_MAPPING[part.type as keyof typeof PART_MAPPING]) const component = createMemo(() => PART_MAPPING[part.type as keyof typeof PART_MAPPING])
function resize(el: BoxRenderable) {
const parent = el.parent
if (!parent) return
const children = parent.getChildren()
const index = children.indexOf(el)
const previous = children[index - 1]
if (!previous) return
console.log(previous.height, el.height)
if (el.height > 1 || previous.height > 1) {
el.marginTop = 1
}
}
return ( return (
<Show when={component()}> <Show when={component()}>
<box
onSizeChange={function () {
resize(this)
}}
ref={(el) => resize(el!)}
>
<Dynamic component={component()} part={part as any} message={props.message} /> <Dynamic component={component()} part={part as any} message={props.message} />
</box>
</Show> </Show>
) )
}} }}
@@ -165,6 +145,17 @@ const PART_MAPPING = {
text: TextPart, text: TextPart,
tool: ToolPart, tool: ToolPart,
} }
function resize(el: BoxRenderable) {
const parent = el.parent
if (!parent) return
const children = parent.getChildren()
const index = children.indexOf(el)
const previous = children[index - 1]
if (!previous) return
if (el.height > 1 || previous.height > 1) {
el.marginTop = 1
}
}
function TextPart(props: { part: TextPart; message: AssistantMessage }) { function TextPart(props: { part: TextPart; message: AssistantMessage }) {
const sync = useSync() const sync = useSync()
@@ -172,7 +163,13 @@ function TextPart(props: { part: TextPart; message: AssistantMessage }) {
const local = useLocal() const local = useLocal()
return ( return (
<box paddingLeft={3}> <box
paddingLeft={3}
onSizeChange={function () {
resize(this)
}}
ref={(el) => resize(el!)}
>
<text>{props.part.text.trim()}</text> <text>{props.part.text.trim()}</text>
<text> <text>
<span style={{ fg: local.agent.color(agent().name) }}>{Locale.titlecase(agent().name)}</span>{" "} <span style={{ fg: local.agent.color(agent().name) }}>{Locale.titlecase(agent().name)}</span>{" "}
@@ -209,7 +206,13 @@ function ToolPart(props: { part: ToolPart; message: AssistantMessage }) {
} }
return ( return (
<box {...container}> <box
{...container}
onSizeChange={function () {
resize(this)
}}
ref={(el) => resize(el!)}
>
<Dynamic <Dynamic
component={ready} component={ready}
input={input} input={input}