mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-25 07:15:19 +00:00
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
110 lines
3.3 KiB
TypeScript
110 lines
3.3 KiB
TypeScript
import { createMemo } from "solid-js"
|
|
import { useSync } from "@tui/context/sync"
|
|
import { DialogSelect } from "@tui/ui/dialog-select"
|
|
import { useSDK } from "@tui/context/sdk"
|
|
import { useRoute } from "@tui/context/route"
|
|
import { Clipboard } from "@tui/util/clipboard"
|
|
import type { PromptInfo } from "@tui/component/prompt/history"
|
|
|
|
export function DialogMessage(props: {
|
|
messageID: string
|
|
sessionID: string
|
|
setPrompt?: (prompt: PromptInfo) => void
|
|
}) {
|
|
const sync = useSync()
|
|
const sdk = useSDK()
|
|
const message = createMemo(() => sync.data.message[props.sessionID]?.find((x) => x.id === props.messageID))
|
|
const route = useRoute()
|
|
|
|
return (
|
|
<DialogSelect
|
|
title="Message Actions"
|
|
options={[
|
|
{
|
|
title: "Revert",
|
|
value: "session.revert",
|
|
description: "undo messages and file changes",
|
|
onSelect: (dialog) => {
|
|
const msg = message()
|
|
if (!msg) return
|
|
|
|
sdk.client.session.revert({
|
|
sessionID: props.sessionID,
|
|
messageID: msg.id,
|
|
})
|
|
|
|
if (props.setPrompt) {
|
|
const parts = sync.data.part[msg.id]
|
|
const promptInfo = parts.reduce(
|
|
(agg, part) => {
|
|
if (part.type === "text") {
|
|
if (!part.synthetic) agg.input += part.text
|
|
}
|
|
if (part.type === "file") agg.parts.push(part)
|
|
return agg
|
|
},
|
|
{ input: "", parts: [] as PromptInfo["parts"] },
|
|
)
|
|
props.setPrompt(promptInfo)
|
|
}
|
|
|
|
dialog.clear()
|
|
},
|
|
},
|
|
{
|
|
title: "Copy",
|
|
value: "message.copy",
|
|
description: "copy message text to clipboard",
|
|
onSelect: async (dialog) => {
|
|
const msg = message()
|
|
if (!msg) return
|
|
|
|
const parts = sync.data.part[msg.id]
|
|
const text = parts.reduce((agg, part) => {
|
|
if (part.type === "text" && !part.synthetic) {
|
|
agg += part.text
|
|
}
|
|
return agg
|
|
}, "")
|
|
|
|
await Clipboard.copy(text)
|
|
dialog.clear()
|
|
},
|
|
},
|
|
{
|
|
title: "Fork",
|
|
value: "session.fork",
|
|
description: "create a new session",
|
|
onSelect: async (dialog) => {
|
|
const result = await sdk.client.session.fork({
|
|
sessionID: props.sessionID,
|
|
messageID: props.messageID,
|
|
})
|
|
const initialPrompt = (() => {
|
|
const msg = message()
|
|
if (!msg) return undefined
|
|
const parts = sync.data.part[msg.id]
|
|
return parts.reduce(
|
|
(agg, part) => {
|
|
if (part.type === "text") {
|
|
if (!part.synthetic) agg.input += part.text
|
|
}
|
|
if (part.type === "file") agg.parts.push(part)
|
|
return agg
|
|
},
|
|
{ input: "", parts: [] as PromptInfo["parts"] },
|
|
)
|
|
})()
|
|
route.navigate({
|
|
sessionID: result.data!.id,
|
|
type: "session",
|
|
initialPrompt,
|
|
})
|
|
dialog.clear()
|
|
},
|
|
},
|
|
]}
|
|
/>
|
|
)
|
|
}
|