mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-21 16:14:45 +00:00
feat(app): restore to message and fork session (#17092)
This commit is contained in:
@@ -129,12 +129,20 @@ function DiagnosticsDisplay(props: { diagnostics: Diagnostic[] }): JSX.Element {
|
||||
export interface MessageProps {
|
||||
message: MessageType
|
||||
parts: PartType[]
|
||||
actions?: UserActions
|
||||
showAssistantCopyPartID?: string | null
|
||||
interrupted?: boolean
|
||||
queued?: boolean
|
||||
showReasoningSummaries?: boolean
|
||||
}
|
||||
|
||||
export type SessionAction = (input: { sessionID: string; messageID: string }) => Promise<void> | void
|
||||
|
||||
export type UserActions = {
|
||||
fork?: SessionAction
|
||||
revert?: SessionAction
|
||||
}
|
||||
|
||||
export interface MessagePartProps {
|
||||
part: PartType
|
||||
message: MessageType
|
||||
@@ -676,6 +684,7 @@ export function Message(props: MessageProps) {
|
||||
<UserMessageDisplay
|
||||
message={userMessage() as UserMessage}
|
||||
parts={props.parts}
|
||||
actions={props.actions}
|
||||
interrupted={props.interrupted}
|
||||
queued={props.queued}
|
||||
/>
|
||||
@@ -872,6 +881,7 @@ function ContextToolGroup(props: { parts: ToolPart[]; busy?: boolean }) {
|
||||
export function UserMessageDisplay(props: {
|
||||
message: UserMessage
|
||||
parts: PartType[]
|
||||
actions?: UserActions
|
||||
interrupted?: boolean
|
||||
queued?: boolean
|
||||
}) {
|
||||
@@ -879,6 +889,7 @@ export function UserMessageDisplay(props: {
|
||||
const dialog = useDialog()
|
||||
const i18n = useI18n()
|
||||
const [copied, setCopied] = createSignal(false)
|
||||
const [busy, setBusy] = createSignal<"fork" | "revert" | undefined>()
|
||||
|
||||
const textPart = createMemo(
|
||||
() => props.parts?.find((p) => p.type === "text" && !(p as TextPart).synthetic) as TextPart | undefined,
|
||||
@@ -945,6 +956,22 @@ export function UserMessageDisplay(props: {
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
|
||||
const run = (kind: "fork" | "revert") => {
|
||||
const act = kind === "fork" ? props.actions?.fork : props.actions?.revert
|
||||
if (!act || busy()) return
|
||||
setBusy(kind)
|
||||
void Promise.resolve()
|
||||
.then(() =>
|
||||
act({
|
||||
sessionID: props.message.sessionID,
|
||||
messageID: props.message.id,
|
||||
}),
|
||||
)
|
||||
.finally(() => {
|
||||
if (busy() === kind) setBusy(undefined)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-component="user-message" data-interrupted={props.interrupted ? "" : undefined}>
|
||||
<Show when={attachments().length > 0}>
|
||||
@@ -1012,6 +1039,38 @@ export function UserMessageDisplay(props: {
|
||||
</Show>
|
||||
</span>
|
||||
</Show>
|
||||
<Show when={props.actions?.fork}>
|
||||
<Tooltip value={i18n.t("ui.message.forkMessage")} placement="top" gutter={4}>
|
||||
<IconButton
|
||||
icon="fork"
|
||||
size="normal"
|
||||
variant="ghost"
|
||||
disabled={!!busy()}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
run("fork")
|
||||
}}
|
||||
aria-label={i18n.t("ui.message.forkMessage")}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<Show when={props.actions?.revert}>
|
||||
<Tooltip value={i18n.t("ui.message.revertMessage")} placement="top" gutter={4}>
|
||||
<IconButton
|
||||
icon="reset"
|
||||
size="normal"
|
||||
variant="ghost"
|
||||
disabled={!!busy()}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
run("revert")
|
||||
}}
|
||||
aria-label={i18n.t("ui.message.revertMessage")}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<Tooltip
|
||||
value={copied() ? i18n.t("ui.message.copied") : i18n.t("ui.message.copyMessage")}
|
||||
placement="top"
|
||||
|
||||
Reference in New Issue
Block a user