110 lines
3.3 KiB
TypeScript
110 lines
3.3 KiB
TypeScript
import { createMemo } from "solid-js"
|
|
import { useSync } from "../../context/sync"
|
|
import { DialogSelect } from "../../ui/dialog-select"
|
|
import { useSDK } from "../../context/sdk"
|
|
import { useRoute } from "../../context/route"
|
|
import { useClipboard } from "../../context/clipboard"
|
|
import type { PromptInfo } from "../../component/prompt/history"
|
|
import { stripPromptPartIDs as strip } from "../../prompt/part"
|
|
|
|
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()
|
|
const clipboard = useClipboard()
|
|
|
|
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
|
|
|
|
void 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(strip(part))
|
|
return agg
|
|
},
|
|
{ input: "", parts: [] as PromptInfo["parts"] },
|
|
)
|
|
props.setPrompt(promptInfo)
|
|
}
|
|
|
|
dialog.clear()
|
|
},
|
|
},
|
|
{
|
|
title: "Copy",
|
|
value: "message.copy",
|
|
description: "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.write?.(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 msg = message()
|
|
const prompt = msg
|
|
? sync.data.part[msg.id].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"] },
|
|
)
|
|
: undefined
|
|
route.navigate({
|
|
sessionID: result.data!.id,
|
|
type: "session",
|
|
prompt,
|
|
})
|
|
dialog.clear()
|
|
},
|
|
},
|
|
]}
|
|
/>
|
|
)
|
|
}
|