mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-03 23:53:46 +00:00
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
import { UserMessage } from "@opencode-ai/sdk/v2"
|
|
import { ComponentProps, For, Match, Show, splitProps, Switch } from "solid-js"
|
|
import { DiffChanges } from "./diff-changes"
|
|
import { Tooltip } from "./tooltip"
|
|
import { useI18n } from "../context/i18n"
|
|
|
|
export function MessageNav(
|
|
props: ComponentProps<"ul"> & {
|
|
messages: UserMessage[]
|
|
current?: UserMessage
|
|
size: "normal" | "compact"
|
|
onMessageSelect: (message: UserMessage) => void
|
|
getLabel?: (message: UserMessage) => string | undefined
|
|
},
|
|
) {
|
|
const i18n = useI18n()
|
|
const [local, others] = splitProps(props, ["messages", "current", "size", "onMessageSelect", "getLabel"])
|
|
|
|
const content = () => (
|
|
<ul role="list" data-component="message-nav" data-size={local.size} {...others}>
|
|
<For each={local.messages}>
|
|
{(message) => {
|
|
const handleClick = () => local.onMessageSelect(message)
|
|
|
|
const handleKeyPress = (event: KeyboardEvent) => {
|
|
if (event.key !== "Enter" && event.key !== " ") return
|
|
event.preventDefault()
|
|
local.onMessageSelect(message)
|
|
}
|
|
|
|
return (
|
|
<li data-slot="message-nav-item">
|
|
<Switch>
|
|
<Match when={local.size === "compact"}>
|
|
<div
|
|
data-slot="message-nav-tick-button"
|
|
data-active={message.id === local.current?.id || undefined}
|
|
role="button"
|
|
tabindex={0}
|
|
onClick={handleClick}
|
|
onKeyDown={handleKeyPress}
|
|
>
|
|
<div data-slot="message-nav-tick-line" />
|
|
</div>
|
|
</Match>
|
|
<Match when={local.size === "normal"}>
|
|
<button data-slot="message-nav-message-button" onClick={handleClick} onKeyDown={handleKeyPress}>
|
|
<DiffChanges changes={message.summary?.diffs ?? []} variant="bars" />
|
|
<div
|
|
data-slot="message-nav-title-preview"
|
|
data-active={message.id === local.current?.id || undefined}
|
|
>
|
|
<Show
|
|
when={local.getLabel?.(message) ?? message.summary?.title}
|
|
fallback={i18n.t("ui.messageNav.newMessage")}
|
|
>
|
|
{local.getLabel?.(message) ?? message.summary?.title}
|
|
</Show>
|
|
</div>
|
|
</button>
|
|
</Match>
|
|
</Switch>
|
|
</li>
|
|
)
|
|
}}
|
|
</For>
|
|
</ul>
|
|
)
|
|
|
|
return (
|
|
<Switch>
|
|
<Match when={local.size === "compact"}>
|
|
<Tooltip
|
|
openDelay={0}
|
|
placement="right-start"
|
|
gutter={-40}
|
|
shift={-10}
|
|
overlap
|
|
contentClass="message-nav-tooltip"
|
|
value={
|
|
<div data-slot="message-nav-tooltip-content">
|
|
<MessageNav {...props} size="normal" class="" />
|
|
</div>
|
|
}
|
|
>
|
|
{content()}
|
|
</Tooltip>
|
|
</Match>
|
|
<Match when={local.size === "normal"}>{content()}</Match>
|
|
</Switch>
|
|
)
|
|
}
|