clean up chatStore

This commit is contained in:
2024-12-27 18:02:14 +08:00
parent 092ac46c15
commit 66a6f263a5
9 changed files with 70 additions and 91 deletions

View File

@@ -1,8 +1,13 @@
import { ChatStore } from "@/types/chatstore";
import { Tr } from "@/translate";
import { useContext } from "react";
import { AppContext } from "@/pages/App";
const VersionHint = (props: { chatStore: ChatStore }) => {
const { chatStore } = props;
const VersionHint = () => {
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { chatStore } = ctx;
return (
<>
{chatStore.chatgpt_api_web_version < "v1.3.0" && (

View File

@@ -1,4 +1,4 @@
import { createRef } from "react";
import { createRef, useContext } from "react";
import { ChatStore } from "@/types/chatstore";
import { useEffect, useState, Dispatch } from "react";
@@ -10,13 +10,17 @@ import {
MicIcon,
VoicemailIcon,
} from "lucide-react";
import { AppContext } from "@/pages/App";
const WhisperButton = (props: {
chatStore: ChatStore;
inputMsg: string;
setInputMsg: Dispatch<string>;
}) => {
const { chatStore, inputMsg, setInputMsg } = props;
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { chatStore } = ctx;
const { inputMsg, setInputMsg } = props;
const mediaRef = createRef();
const [isRecording, setIsRecording] = useState("Mic");
return (

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, Dispatch } from "react";
import { useState, useEffect, Dispatch, useContext } from "react";
import { Tr, langCodeContext, LANG_OPTIONS, tr } from "@/translate";
import { ChatStore, ChatStoreMessage } from "@/types/chatstore";
import { EditMessageString } from "@/editMessageString";
@@ -13,16 +13,18 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "./components/ui/button";
import { AppContext } from "./pages/App";
interface EditMessageProps {
chat: ChatStoreMessage;
chatStore: ChatStore;
showEdit: boolean;
setShowEdit: Dispatch<boolean>;
setChatStore: (cs: ChatStore) => void;
}
export function EditMessage(props: EditMessageProps) {
const { showEdit, setShowEdit, chat, setChatStore, chatStore } = props;
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { showEdit, setShowEdit, chat } = props;
return (
<Dialog open={showEdit} onOpenChange={setShowEdit}>
@@ -37,21 +39,11 @@ export function EditMessage(props: EditMessageProps) {
</DialogDescription>
</DialogHeader>
{typeof chat.content === "string" ? (
<EditMessageString
chat={chat}
chatStore={chatStore}
setChatStore={setChatStore}
setShowEdit={setShowEdit}
/>
<EditMessageString chat={chat} setShowEdit={setShowEdit} />
) : (
<EditMessageDetail
chat={chat}
chatStore={chatStore}
setChatStore={setChatStore}
setShowEdit={setShowEdit}
/>
<EditMessageDetail chat={chat} setShowEdit={setShowEdit} />
)}
{chatStore.develop_mode && (
{ctx.chatStore.develop_mode && (
<Button
variant="destructive"
className="w-full"
@@ -66,7 +58,7 @@ export function EditMessage(props: EditMessageProps) {
} else {
chat.content = "";
}
setChatStore({ ...chatStore });
ctx.setChatStore({ ...ctx.chatStore });
}}
>
Switch to{" "}

View File

@@ -14,19 +14,19 @@ import {
} from "@/components/ui/drawer";
import { Button } from "./components/ui/button";
import { useContext } from "react";
import { AppContext } from "./pages/App";
interface Props {
chat: ChatStoreMessage;
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
setShowEdit: (se: boolean) => void;
}
export function EditMessageDetail({
chat,
chatStore,
setChatStore,
setShowEdit,
}: Props) {
export function EditMessageDetail({ chat, setShowEdit }: Props) {
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { chatStore, setChatStore } = ctx;
if (typeof chat.content !== "object") return <div>error</div>;
return (
<Drawer open={true} onOpenChange={setShowEdit}>

View File

@@ -4,19 +4,19 @@ import { calculate_token_length } from "@/chatgpt";
import { Tr } from "@/translate";
import { Textarea } from "@/components/ui/textarea";
import { useContext } from "react";
import { AppContext } from "./pages/App";
interface Props {
chat: ChatStoreMessage;
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
setShowEdit: (se: boolean) => void;
}
export function EditMessageString({
chat,
chatStore,
setChatStore,
setShowEdit,
}: Props) {
export function EditMessageString({ chat, setShowEdit }: Props) {
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { chatStore, setChatStore } = ctx;
if (typeof chat.content !== "string") return <div>error</div>;
return (
<div className="flex flex-col">

View File

@@ -12,19 +12,15 @@ import {
} from "@/components/ui/navigation-menu";
import { cn } from "@/lib/utils";
import { Button } from "./components/ui/button";
import { useContext } from "react";
import { AppContext } from "./pages/App";
export function ListToolsTempaltes() {
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
const { chatStore, setChatStore } = ctx;
interface Props {
templateTools: TemplateTools[];
setTemplateTools: (tmps: TemplateTools[]) => void;
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
}
export function ListToolsTempaltes({
chatStore,
templateTools,
setTemplateTools,
setChatStore,
}: Props) {
return (
<NavigationMenuItem className="p-3">
<NavigationMenuTrigger>
@@ -42,7 +38,7 @@ export function ListToolsTempaltes({
</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
{templateTools.map((t, index) => (
{ctx.templateTools.map((t, index) => (
<li key={index}>
<NavigationMenuLink asChild>
<a
@@ -73,7 +69,7 @@ export function ListToolsTempaltes({
const name = prompt(`Give **tools** template a name`);
if (!name) return;
t.name = name;
setTemplateTools(structuredClone(templateTools));
ctx.setTemplateTools(structuredClone(ctx.templateTools));
}}
>
Edit
@@ -89,8 +85,8 @@ export function ListToolsTempaltes({
) {
return;
}
templateTools.splice(index, 1);
setTemplateTools(structuredClone(templateTools));
ctx.templateTools.splice(index, 1);
ctx.setTemplateTools(structuredClone(ctx.templateTools));
}}
>
Delete

View File

@@ -208,23 +208,11 @@ export default function Message(props: { messageIndex: number }) {
icon={<ClipboardIcon className="size-4" />}
onClick={() => copyToClipboard(getMessageText(chat))}
/>
{chatStore.tts_api && chatStore.tts_key && (
<TTSButton
chatStore={chatStore}
chat={chat}
setChatStore={setChatStore}
/>
)}
{chatStore.tts_api && chatStore.tts_key && <TTSButton chat={chat} />}
<TTSPlay chat={chat} />
</ChatBubbleActionWrapper>
</ChatBubble>
<EditMessage
showEdit={showEdit}
setShowEdit={setShowEdit}
chat={chat}
chatStore={chatStore}
setChatStore={setChatStore}
/>
<EditMessage showEdit={showEdit} setShowEdit={setShowEdit} chat={chat} />
{chatStore.develop_mode && (
<div
className={`flex flex-wrap items-center gap-2 mt-2 ${

View File

@@ -454,14 +454,7 @@ export default function ChatBOX() {
keyField="image_gen_key"
/>
)}
{ctx.templateTools.length > 0 && (
<ListToolsTempaltes
templateTools={ctx.templateTools}
setTemplateTools={ctx.setTemplateTools}
chatStore={chatStore}
setChatStore={setChatStore}
/>
)}
{ctx.templateTools.length > 0 && <ListToolsTempaltes />}
</NavigationMenuList>
</NavigationMenu>
</div>
@@ -599,7 +592,7 @@ export default function ChatBOX() {
</Alert>
)}
</p>
<VersionHint chatStore={chatStore} />
<VersionHint />
{showRetry && (
<p className="text-right p-2 my-2 dark:text-white">
<Button
@@ -681,7 +674,6 @@ export default function ChatBOX() {
{chatStore.whisper_api && chatStore.whisper_key && (
<>
<WhisperButton
chatStore={chatStore}
inputMsg={inputMsg}
setInputMsg={setInputMsg}
/>

View File

@@ -1,16 +1,15 @@
import { SpeakerWaveIcon } from "@heroicons/react/24/outline";
import { useMemo, useState } from "react";
import { useContext, useMemo, useState } from "react";
import { addTotalCost } from "@/utils/totalCost";
import { ChatStore, ChatStoreMessage } from "@/types/chatstore";
import { Message, getMessageText } from "@/chatgpt";
import { AudioLinesIcon, LoaderCircleIcon } from "lucide-react";
import { Button } from "./components/ui/button";
import { AppContext } from "./pages/App";
interface TTSProps {
chatStore: ChatStore;
chat: ChatStoreMessage;
setChatStore: (cs: ChatStore) => void;
}
interface TTSPlayProps {
chat: ChatStoreMessage;
@@ -33,25 +32,28 @@ export function TTSPlay(props: TTSPlayProps) {
}
export default function TTSButton(props: TTSProps) {
const [generating, setGenerating] = useState(false);
const ctx = useContext(AppContext);
if (!ctx) return <div>error</div>;
return (
<Button
variant="ghost"
size="icon"
onClick={() => {
const api = props.chatStore.tts_api;
const api_key = props.chatStore.tts_key;
const api = ctx.chatStore.tts_api;
const api_key = ctx.chatStore.tts_key;
const model = "tts-1";
const input = getMessageText(props.chat);
const voice = props.chatStore.tts_voice;
const voice = ctx.chatStore.tts_voice;
const body: Record<string, any> = {
model,
input,
voice,
response_format: props.chatStore.tts_format || "mp3",
response_format: ctx.chatStore.tts_format || "mp3",
};
if (props.chatStore.tts_speed_enabled) {
body["speed"] = props.chatStore.tts_speed;
if (ctx.chatStore.tts_speed_enabled) {
body["speed"] = ctx.chatStore.tts_speed;
}
setGenerating(true);
@@ -68,13 +70,13 @@ export default function TTSButton(props: TTSProps) {
.then((blob) => {
// update price
const cost = (input.length * 0.015) / 1000;
props.chatStore.cost += cost;
ctx.chatStore.cost += cost;
addTotalCost(cost);
props.setChatStore({ ...props.chatStore });
ctx.setChatStore({ ...ctx.chatStore });
// save blob
props.chat.audio = blob;
props.setChatStore({ ...props.chatStore });
ctx.setChatStore({ ...ctx.chatStore });
const url = URL.createObjectURL(blob);
const audio = new Audio(url);