fix copy render msg

This commit is contained in:
2023-11-10 17:12:57 +08:00
parent 626e7780f8
commit 33f4ab7b42
3 changed files with 85 additions and 45 deletions

View File

@@ -47,6 +47,14 @@ export interface StreamingResponseChunk {
} }
export const getMessageText = (message: Message): string => { export const getMessageText = (message: Message): string => {
if (typeof message.content === "string") { if (typeof message.content === "string") {
// function call message
if (message.tool_calls) {
return message.tool_calls
.map((tc) => {
return `Tool Call ID: ${tc.id}\nType: ${tc.type}\nFunction: ${tc.function.name}\nArguments: ${tc.function.arguments}}`;
})
.join("\n");
}
return message.content; return message.content;
} }
return message.content return message.content

View File

@@ -28,6 +28,6 @@ body::-webkit-scrollbar {
display: none; display: none;
} }
p.message-content { .message-content {
white-space: pre-wrap; white-space: pre-wrap;
} }

View File

@@ -245,14 +245,18 @@ export default function Message(props: Props) {
</span> </span>
); );
const CopyIcon = () => { const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
setShowCopiedHint(true);
setTimeout(() => setShowCopiedHint(false), 1000);
};
const CopyIcon = ({ textToCopy }: { textToCopy: string }) => {
return ( return (
<> <>
<button <button
onClick={() => { onClick={() => {
navigator.clipboard.writeText(getMessageText(chat)); copyToClipboard(textToCopy);
setShowCopiedHint(true);
setTimeout(() => setShowCopiedHint(false), 1000);
}} }}
> >
📋 📋
@@ -288,59 +292,87 @@ export default function Message(props: Props) {
: "bg-green-400" : "bg-green-400"
} ${chat.hide ? "opacity-50" : ""}`} } ${chat.hide ? "opacity-50" : ""}`}
> >
{chat.tool_calls && chat.hide ? ( {chat.hide ? (
<div className="message-content">Tool Call</div> getMessageText(chat).split("\n")[0].slice(0, 18) + "... (deleted)"
) : typeof chat.content !== "string" ? (
chat.content.map((mdt) =>
mdt.type === "text" ? (
chat.hide ? (
mdt.text?.split("\n")[0].slice(0, 16) + "... (deleted)"
) : renderMarkdown ? (
// @ts-ignore
<Markdown markdown={mdt.text} />
) : (
mdt.text
)
) : (
<img
className="cursor-pointer max-w-xs max-h-32 p-1"
src={mdt.image_url?.url}
onClick={() => {
window.open(mdt.image_url?.url, "_blank");
}}
/>
)
)
) : renderMarkdown ? (
// @ts-ignore
<Markdown markdown={getMessageText(chat)} />
) : ( ) : (
<div className="message-content">
{
// only show when content is string or list of message
chat.content && getMessageText(chat)
}
</div>
)}
{chat.tool_calls && (
<div className="message-content"> <div className="message-content">
<div> <div>
{chat.tool_calls?.map((tool_call) => ( {chat.tool_calls?.map((tool_call) => (
<> <>
<hr className="my-1" /> <hr className="my-1" />
<div className="bg-blue-300 dark:bg-blue-800 p-1 rounded"> <div className="bg-blue-300 dark:bg-blue-800 p-1 rounded">
<strong>Tool Call ID: {tool_call?.id}</strong> <strong>
Tool Call ID:{" "}
<span
className="p-1 m-1 rounded cursor-pointer hover:opacity-50 hover:underline"
onClick={() =>
copyToClipboard(String(tool_call.id))
}
>
{tool_call?.id}
</span>
</strong>
<p>Type: {tool_call?.type}</p> <p>Type: {tool_call?.type}</p>
<p>Function: {tool_call.function.name}</p> <p>
<p>Arguments: {tool_call.function.arguments}</p> Function:
<span
className="p-1 m-1 rounded cursor-pointer hover:opacity-50 hover:underline"
onClick={() =>
copyToClipboard(tool_call.function.name)
}
>
{tool_call.function.name}
</span>
</p>
<p>
Arguments:
<span
className="p-1 m-1 rounded cursor-pointer hover:opacity-50 hover:underline"
onClick={() =>
copyToClipboard(tool_call.function.arguments)
}
>
{tool_call.function.arguments}
</span>
</p>
</div> </div>
</> </>
))} ))}
</div> </div>
</div> </div>
)} )}
<p className={renderMarkdown ? "" : "message-content"}>
{typeof chat.content !== "string" ? (
// render for multiple messages
chat.content.map((mdt) =>
mdt.type === "text" ? (
chat.hide ? (
mdt.text?.split("\n")[0].slice(0, 16) + "... (deleted)"
) : renderMarkdown ? (
// @ts-ignore
<Markdown markdown={mdt.text} />
) : (
mdt.text
)
) : (
<img
className="cursor-pointer max-w-xs max-h-32 p-1"
src={mdt.image_url?.url}
onClick={() => {
window.open(mdt.image_url?.url, "_blank");
}}
/>
)
)
) : // render for single message
chat.hide ? (
getMessageText(chat).split("\n")[0].slice(0, 16) +
"... (deleted)"
) : renderMarkdown ? (
// @ts-ignore
<Markdown markdown={getMessageText(chat)} />
) : (
getMessageText(chat)
)}
</p>
<hr className="mt-2" /> <hr className="mt-2" />
<div className="w-full flex justify-between"> <div className="w-full flex justify-between">
<DeleteIcon /> <DeleteIcon />
@@ -352,7 +384,7 @@ export default function Message(props: Props) {
setChatStore={setChatStore} setChatStore={setChatStore}
/> />
)} )}
<CopyIcon /> <CopyIcon textToCopy={getMessageText(chat)} />
</div> </div>
</div> </div>
{showEdit && ( {showEdit && (