diff --git a/src/message.tsx b/src/components/MessageBubble.tsx
similarity index 72%
rename from src/message.tsx
rename to src/components/MessageBubble.tsx
index 2784854..d99bd38 100644
--- a/src/message.tsx
+++ b/src/components/MessageBubble.tsx
@@ -1,15 +1,11 @@
import { XMarkIcon } from "@heroicons/react/24/outline";
import Markdown from "react-markdown";
import { useContext, useState } from "react";
+import { ChatStoreMessage } from "@/types/chatstore";
-import { Tr, langCodeContext, LANG_OPTIONS } from "@/translate";
-import { ChatStore, ChatStoreMessage } from "@/types/chatstore";
-import { calculate_token_length, getMessageText } from "@/chatgpt";
+import { Tr } from "@/translate";
+import { getMessageText } from "@/chatgpt";
import TTSButton, { TTSPlay } from "@/tts";
-import { MessageHide } from "@/messageHide";
-import { MessageDetail } from "@/messageDetail";
-import { MessageToolCall } from "@/messageToolCall";
-import { MessageToolResp } from "@/messageToolResp";
import { EditMessage } from "@/editMessage";
import logprobToColor from "@/utils/logprob";
import {
@@ -18,6 +14,7 @@ import {
ChatBubbleAction,
ChatBubbleActionWrapper,
} from "@/components/ui/chat/chat-bubble";
+import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
import {
ClipboardIcon,
@@ -25,16 +22,126 @@ import {
MessageSquareOffIcon,
MessageSquarePlusIcon,
} from "lucide-react";
-import { AppContext } from "./pages/App";
+import { AppContext } from "@/pages/App";
-export const isVailedJSON = (str: string): boolean => {
- try {
- JSON.parse(str);
- } catch (e) {
- return false;
+interface HideMessageProps {
+ chat: ChatStoreMessage;
+}
+
+function MessageHide({ chat }: HideMessageProps) {
+ return (
+ <>
+
+ {getMessageText(chat).split("\n")[0].slice(0, 28)} ...
+
+
+ Removed from context
+
+ >
+ );
+}
+
+interface MessageDetailProps {
+ chat: ChatStoreMessage;
+ renderMarkdown: boolean;
+}
+function MessageDetail({ chat, renderMarkdown }: MessageDetailProps) {
+ if (typeof chat.content === "string") {
+ return ;
}
- return true;
-};
+ return (
+
+ {chat.content.map((mdt) =>
+ mdt.type === "text" ? (
+ chat.hide ? (
+ mdt.text?.split("\n")[0].slice(0, 16) + " ..."
+ ) : renderMarkdown ? (
+
{mdt.text}
+ ) : (
+ mdt.text
+ )
+ ) : (
+

{
+ window.open(mdt.image_url?.url, "_blank");
+ }}
+ />
+ )
+ )}
+
+ );
+}
+
+interface ToolCallMessageProps {
+ chat: ChatStoreMessage;
+ copyToClipboard: (text: string) => void;
+}
+function MessageToolCall({ chat, copyToClipboard }: ToolCallMessageProps) {
+ return (
+
+ {chat.tool_calls?.map((tool_call) => (
+
+
+ Tool Call ID:{" "}
+ copyToClipboard(String(tool_call.id))}
+ >
+ {tool_call?.id}
+
+
+
Type: {tool_call?.type}
+
+ Function:
+ copyToClipboard(tool_call.function.name)}
+ >
+ {tool_call.function.name}
+
+
+
+ Arguments:
+ copyToClipboard(tool_call.function.arguments)}
+ >
+ {tool_call.function.arguments}
+
+
+
+ ))}
+ {/* [TODO] */}
+ {chat.content as string}
+
+ );
+}
+
+interface ToolRespondMessageProps {
+ chat: ChatStoreMessage;
+ copyToClipboard: (text: string) => void;
+}
+function MessageToolResp({ chat, copyToClipboard }: ToolRespondMessageProps) {
+ return (
+
+
+
+ Tool Response ID:{" "}
+ copyToClipboard(String(chat.tool_call_id))}
+ >
+ {chat.tool_call_id}
+
+
+ {/* [TODO] */}
+
{chat.content as string}
+
+
+ );
+}
export default function Message(props: { messageIndex: number }) {
const ctx = useContext(AppContext);
@@ -44,7 +151,6 @@ export default function Message(props: { messageIndex: number }) {
const chat = chatStore.history[messageIndex];
const [showEdit, setShowEdit] = useState(false);
- const [showCopiedHint, setShowCopiedHint] = useState(false);
const [renderMarkdown, setRenderWorkdown] = useState(false);
const [renderColor, setRenderColor] = useState(false);
const DeleteIcon = () => (
diff --git a/src/messageDetail.tsx b/src/messageDetail.tsx
deleted file mode 100644
index 63d7cd9..0000000
--- a/src/messageDetail.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { ChatStoreMessage } from "@/types/chatstore";
-import Markdown from "react-markdown";
-
-interface Props {
- chat: ChatStoreMessage;
- renderMarkdown: boolean;
-}
-export function MessageDetail({ chat, renderMarkdown }: Props) {
- if (typeof chat.content === "string") {
- return ;
- }
- return (
-
- {chat.content.map((mdt) =>
- mdt.type === "text" ? (
- chat.hide ? (
- mdt.text?.split("\n")[0].slice(0, 16) + " ..."
- ) : renderMarkdown ? (
-
{mdt.text}
- ) : (
- mdt.text
- )
- ) : (
-

{
- window.open(mdt.image_url?.url, "_blank");
- }}
- />
- )
- )}
-
- );
-}
diff --git a/src/messageHide.tsx b/src/messageHide.tsx
deleted file mode 100644
index 82b2ac4..0000000
--- a/src/messageHide.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { ChatStoreMessage } from "@/types/chatstore";
-import { getMessageText } from "@/chatgpt";
-import { Badge } from "./components/ui/badge";
-
-interface Props {
- chat: ChatStoreMessage;
-}
-
-export function MessageHide({ chat }: Props) {
- return (
- <>
-
- {getMessageText(chat).split("\n")[0].slice(0, 28)} ...
-
-
- Removed from context
-
- >
- );
-}
diff --git a/src/messageToolCall.tsx b/src/messageToolCall.tsx
deleted file mode 100644
index 7957f21..0000000
--- a/src/messageToolCall.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { ChatStoreMessage } from "@/types/chatstore";
-
-interface Props {
- chat: ChatStoreMessage;
- copyToClipboard: (text: string) => void;
-}
-export function MessageToolCall({ chat, copyToClipboard }: Props) {
- return (
-
- {chat.tool_calls?.map((tool_call) => (
-
-
- Tool Call ID:{" "}
- copyToClipboard(String(tool_call.id))}
- >
- {tool_call?.id}
-
-
-
Type: {tool_call?.type}
-
- Function:
- copyToClipboard(tool_call.function.name)}
- >
- {tool_call.function.name}
-
-
-
- Arguments:
- copyToClipboard(tool_call.function.arguments)}
- >
- {tool_call.function.arguments}
-
-
-
- ))}
- {/* [TODO] */}
- {chat.content as string}
-
- );
-}
diff --git a/src/messageToolResp.tsx b/src/messageToolResp.tsx
deleted file mode 100644
index 2968d03..0000000
--- a/src/messageToolResp.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { ChatStoreMessage } from "@/types/chatstore";
-
-interface Props {
- chat: ChatStoreMessage;
- copyToClipboard: (text: string) => void;
-}
-export function MessageToolResp({ chat, copyToClipboard }: Props) {
- return (
-
-
-
- Tool Response ID:{" "}
- copyToClipboard(String(chat.tool_call_id))}
- >
- {chat.tool_call_id}
-
-
- {/* [TODO] */}
-
{chat.content as string}
-
-
- );
-}
diff --git a/src/pages/App.tsx b/src/pages/App.tsx
index 6a7cf7a..b4e7d20 100644
--- a/src/pages/App.tsx
+++ b/src/pages/App.tsx
@@ -215,6 +215,10 @@ export function App() {
const newKey = await (await db).add(STORAGE_NAME, newChatStore(chatStore));
setSelectedChatIndex(newKey as number);
setAllChatStoreIndexes(await (await db).getAllKeys(STORAGE_NAME));
+ toast({
+ title: "New chat session created",
+ description: `A new chat session (ID. ${newKey}) has been created.`,
+ });
};
const handleNewChatStore = async () => {
return handleNewChatStoreWithOldOne(chatStore);
diff --git a/src/pages/Chatbox.tsx b/src/pages/Chatbox.tsx
index f8d2b5f..a06175f 100644
--- a/src/pages/Chatbox.tsx
+++ b/src/pages/Chatbox.tsx
@@ -12,7 +12,7 @@ import ChatGPT, {
Usage,
} from "@/chatgpt";
import { ChatStoreMessage } from "../types/chatstore";
-import Message from "@/message";
+import Message from "@/components/MessageBubble";
import { models } from "@/types/models";
import { AddImage } from "@/addImage";
import { ListAPIs } from "@/listAPIs";