Refactor EditMessage component to use Dialog for improved user experience; replace textarea with custom Textarea component for better styling and functionality

This commit is contained in:
ecwu
2024-12-21 18:06:03 +08:00
parent 05d9132c22
commit bb2b6164d6
3 changed files with 62 additions and 59 deletions

View File

@@ -4,28 +4,38 @@ import { ChatStore, ChatStoreMessage } from "@/types/chatstore";
import { EditMessageString } from "@/editMessageString"; import { EditMessageString } from "@/editMessageString";
import { EditMessageDetail } from "@/editMessageDetail"; import { EditMessageDetail } from "@/editMessageDetail";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "./components/ui/button";
interface EditMessageProps { interface EditMessageProps {
chat: ChatStoreMessage; chat: ChatStoreMessage;
chatStore: ChatStore; chatStore: ChatStore;
showEdit: boolean;
setShowEdit: Dispatch<StateUpdater<boolean>>; setShowEdit: Dispatch<StateUpdater<boolean>>;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
} }
export function EditMessage(props: EditMessageProps) { export function EditMessage(props: EditMessageProps) {
const { setShowEdit, chat, setChatStore, chatStore } = props; const { showEdit, setShowEdit, chat, setChatStore, chatStore } = props;
return ( return (
<div <Dialog open={showEdit} onOpenChange={setShowEdit}>
className={ {/* <DialogTrigger>
"absolute bg-black bg-opacity-50 w-full h-full top-0 left-0 rounded z-10 overflow-scroll" <button className="btn btn-sm btn-outline"></button>
} </DialogTrigger> */}
onClick={() => setShowEdit(false)} <DialogContent className="sm:max-w-[425px]">
> <DialogHeader>
<div <DialogTitle>Edit Message</DialogTitle>
className="m-10 p-2 bg-white rounded" <DialogDescription>
onClick={(event: any) => { Make changes to the message content.
event.stopPropagation(); </DialogDescription>
}} </DialogHeader>
>
{typeof chat.content === "string" ? ( {typeof chat.content === "string" ? (
<EditMessageString <EditMessageString
chat={chat} chat={chat}
@@ -41,13 +51,13 @@ export function EditMessage(props: EditMessageProps) {
setShowEdit={setShowEdit} setShowEdit={setShowEdit}
/> />
)} )}
<div className={"w-full flex justify-center"}>
{chatStore.develop_mode && ( {chatStore.develop_mode && (
<button <Button
className="w-full m-2 p-1 rounded bg-red-500" variant="destructive"
className="w-full"
onClick={() => { onClick={() => {
const confirm = window.confirm( const confirm = window.confirm(
"Change message type will clear the content, are you sure?", "Change message type will clear the content, are you sure?"
); );
if (!confirm) return; if (!confirm) return;
@@ -63,18 +73,10 @@ export function EditMessage(props: EditMessageProps) {
{typeof chat.content === "string" {typeof chat.content === "string"
? "media message" ? "media message"
: "string message"} : "string message"}
</button> </Button>
)} )}
<button <Button onClick={() => setShowEdit(false)}>Save & Close</Button>
className={"w-full m-2 p-1 rounded bg-purple-500"} </DialogContent>
onClick={() => { </Dialog>
setShowEdit(false);
}}
>
{Tr("Close")}
</button>
</div>
</div>
</div>
); );
} }

View File

@@ -3,6 +3,8 @@ import { isVailedJSON } from "@/message";
import { calculate_token_length } from "@/chatgpt"; import { calculate_token_length } from "@/chatgpt";
import { Tr } from "@/translate"; import { Tr } from "@/translate";
import { Textarea } from "@/components/ui/textarea";
interface Props { interface Props {
chat: ChatStoreMessage; chat: ChatStoreMessage;
chatStore: ChatStore; chatStore: ChatStore;
@@ -69,7 +71,7 @@ export function EditMessageString({
onClick={() => { onClick={() => {
if (!chat.tool_calls) return; if (!chat.tool_calls) return;
chat.tool_calls = chat.tool_calls.filter( chat.tool_calls = chat.tool_calls.filter(
(tc) => tc.id !== tool_call.id, (tc) => tc.id !== tool_call.id
); );
setChatStore({ ...chatStore }); setChatStore({ ...chatStore });
}} }}
@@ -100,20 +102,20 @@ export function EditMessageString({
</span> </span>
</div> </div>
))} ))}
<textarea <Textarea
className="rounded border border-gray-400 w-full h-32 my-2" className="w-full h-32 my-2"
value={chat.content} value={chat.content}
onChange={(event: any) => { onChange={(event) => {
chat.content = event.target.value; chat.content = event.target.value;
chat.token = calculate_token_length(chat.content); chat.token = calculate_token_length(chat.content);
setChatStore({ ...chatStore }); setChatStore({ ...chatStore });
}} }}
onKeyPress={(event: any) => { onKeyPress={(event) => {
if (event.keyCode == 27) { if (event.keyCode == 27) {
setShowEdit(false); setShowEdit(false);
} }
}} }}
></textarea> />
</div> </div>
); );
} }

View File

@@ -189,14 +189,13 @@ export default function Message(props: Props) {
<TTSPlay chat={chat} /> <TTSPlay chat={chat} />
</ChatBubbleActionWrapper> </ChatBubbleActionWrapper>
</ChatBubble> </ChatBubble>
{showEdit && (
<EditMessage <EditMessage
showEdit={showEdit}
setShowEdit={setShowEdit} setShowEdit={setShowEdit}
chat={chat} chat={chat}
chatStore={chatStore} chatStore={chatStore}
setChatStore={setChatStore} setChatStore={setChatStore}
/> />
)}
{chatStore.develop_mode && ( {chatStore.develop_mode && (
<div <div
className={`flex flex-wrap items-center gap-2 mt-2 ${ className={`flex flex-wrap items-center gap-2 mt-2 ${