feat(desktop): improve file comments in session timeline (#36845)

Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
This commit is contained in:
usrnk1 2026-07-14 15:12:46 +02:00 committed by GitHub
commit dedb4133dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 274 additions and 115 deletions

View file

@ -12,6 +12,16 @@
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-base);
cursor: default;
&[data-wide] {
width: 100%;
min-width: 0;
max-width: none;
}
&[data-surface="base"] {
background: var(--v2-background-bg-base);
}
&[data-active] {
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-strong);
}
@ -32,6 +42,8 @@
}
[data-slot="attachment-card-v2-title"] {
width: 100%;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

View file

@ -6,8 +6,11 @@ export function AttachmentCardV2(props: {
title: string
active?: boolean
clickable?: boolean
wide?: boolean
surface?: "base"
/** native title attribute */
hover?: string
titleRef?: (element: HTMLSpanElement) => void
onClick?: () => void
children: JSX.Element
}) {
@ -16,10 +19,14 @@ export function AttachmentCardV2(props: {
data-component="attachment-card-v2"
data-active={props.active ? "true" : undefined}
data-clickable={props.clickable ? "true" : undefined}
data-wide={props.wide ? "true" : undefined}
data-surface={props.surface}
title={props.hover}
onClick={() => props.onClick?.()}
>
<span data-slot="attachment-card-v2-title">{props.title}</span>
<span ref={(element) => props.titleRef?.(element)} data-slot="attachment-card-v2-title">
{props.title}
</span>
<span data-slot="attachment-card-v2-subtitle">{props.children}</span>
</div>
)

View file

@ -1,6 +1,7 @@
import { Show } from "solid-js"
import { createSignal, onCleanup, onMount, Show } from "solid-js"
import { FileIcon } from "@opencode-ai/ui/file-icon"
import { getFilenameTruncated } from "@opencode-ai/core/util/path"
import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
import { AttachmentCardV2 } from "./attachment-card-v2"
export function CommentCardV2(props: {
@ -9,19 +10,55 @@ export function CommentCardV2(props: {
selection?: { startLine: number; endLine: number }
active?: boolean
title?: string
tooltip?: boolean
wide?: boolean
onClick?: () => void
}) {
let title: HTMLSpanElement | undefined
const [truncated, setTruncated] = createSignal(false)
onMount(() => {
const element = title
if (!element) return
const sync = () => setTruncated(element.scrollWidth > element.clientWidth)
const measure = () => requestAnimationFrame(sync)
const observer = new ResizeObserver(sync)
observer.observe(element)
measure()
void document.fonts?.ready.then(measure)
onCleanup(() => observer.disconnect())
})
return (
<AttachmentCardV2 title={props.comment} active={props.active} hover={props.title} onClick={props.onClick}>
<FileIcon node={{ path: props.path, type: "file" }} />
<span>
{getFilenameTruncated(props.path, 14)}
<Show when={props.selection}>
{(sel) =>
sel().startLine === sel().endLine ? `:${sel().startLine}` : `:${sel().startLine}-${sel().endLine}`
}
</Show>
</span>
</AttachmentCardV2>
<TooltipV2
placement="top"
openDelay={1000}
value={props.title ?? props.comment}
disabled={!props.tooltip || !truncated()}
class={props.wide ? "w-full" : undefined}
contentStyle={{ "max-width": "320px", "white-space": "pre-wrap" }}
>
<AttachmentCardV2
title={props.comment}
active={props.active}
clickable={!!props.onClick}
wide={props.wide}
surface="base"
titleRef={(element) => {
title = element
}}
onClick={props.onClick}
>
<FileIcon node={{ path: props.path, type: "file" }} />
<span>
{getFilenameTruncated(props.path, 14)}
<Show when={props.selection}>
{(sel) =>
sel().startLine === sel().endLine ? `:${sel().startLine}` : `:${sel().startLine}-${sel().endLine}`
}
</Show>
</span>
</AttachmentCardV2>
</TooltipV2>
)
}