import { Tr, langCodeContext, LANG_OPTIONS } from "./translate"; import { useState, useEffect, StateUpdater } from "preact/hooks"; import { ChatStore, ChatStoreMessage } from "./app"; import { calculate_token_length, getMessageText } from "./chatgpt"; import Markdown from "preact-markdown"; 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 "./logprob"; export const isVailedJSON = (str: string): boolean => { try { JSON.parse(str); } catch (e) { return false; } return true; }; interface Props { messageIndex: number; chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; update_total_tokens: () => void; } export default function Message(props: Props) { const { chatStore, messageIndex, setChatStore } = props; 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 = () => ( ); const CopiedHint = () => ( {Tr("Message copied to clipboard!")} ); const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); setShowCopiedHint(true); setTimeout(() => setShowCopiedHint(false), 1000); }; const CopyIcon = ({ textToCopy }: { textToCopy: string }) => { return ( <> ); }; return ( <> {chatStore.postBeginIndex !== 0 && !chatStore.history[messageIndex].hide && chatStore.postBeginIndex === chatStore.history.slice(0, messageIndex).filter(({ hide }) => !hide) .length && (

Above messages are "forgotten"
)}
{chat.hide ? ( ) : typeof chat.content !== "string" ? ( ) : chat.tool_calls ? ( ) : chat.role === "tool" ? ( ) : renderMarkdown ? ( // @ts-ignore ) : (
{ // only show when content is string or list of message // this check is used to avoid rendering tool call chat.content && (chat.logprobs && renderColor ? chat.logprobs.content .filter((c) => c.token) .map((c) => (
{c.token}
)) : getMessageText(chat)) }
)}
{chatStore.tts_api && chatStore.tts_key && ( )}
{showEdit && ( )} {showCopiedHint && } {chatStore.develop_mode && (
token { chat.token = parseInt(event.target.value); props.update_total_tokens(); setChatStore({ ...chatStore }); }} /> { chat.example = !chat.example; setChatStore({ ...chatStore }); }} > setRenderWorkdown(!renderMarkdown)} > setRenderColor(!renderColor)}>
)}
); }