Refactor ChatBOX component to enhance input handling and UI elements

This commit is contained in:
ecwu
2024-12-20 18:37:09 +08:00
parent 5ecfe13234
commit 5f6d83000d

View File

@@ -42,14 +42,10 @@ import WhisperButton from "@/components/WhisperButton";
import AddToolMsg from "./AddToolMsg"; import AddToolMsg from "./AddToolMsg";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import { ChatInput } from "@/components/ui/chat/chat-input";
ChatBubble,
ChatBubbleAvatar,
ChatBubbleMessage,
ChatBubbleAction,
ChatBubbleActionWrapper,
} from "@/components/ui/chat/chat-bubble";
import { ChatMessageList } from "@/components/ui/chat/chat-message-list"; import { ChatMessageList } from "@/components/ui/chat/chat-message-list";
import { CornerDownLeftIcon, ImageIcon } from "lucide-react";
import { Switch } from "@/components/ui/switch";
export default function ChatBOX(props: { export default function ChatBOX(props: {
db: Promise<IDBPDatabase<ChatStore>>; db: Promise<IDBPDatabase<ChatStore>>;
@@ -684,42 +680,24 @@ export default function ChatBOX(props: {
)} )}
{generatingMessage && ( {generatingMessage && (
<span <div className="flex items-center justify-end gap-2 p-2 m-2 rounded bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
className="p-2 m-2 rounded bg-white dark:text-black dark:bg-white dark:bg-opacity-50" <label className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
style={{ textAlign: "right" }} Follow
onClick={() => { </label>
setFollow(!follow); <Switch
}} checked={follow}
> onCheckedChange={setFollow}
<label>Follow</label> aria-label="Toggle auto-scroll"
<input type="checkbox" checked={follow} /> />
</span> </div>
)} )}
<div className="sticky top-0 z-10 bg-background flex justify-between my-1 gap-2 p-2"> <div className="sticky top-0 z-10 bg-background">
<Button <form className="relative rounded-lg border bg-background focus-within:ring-1 focus-within:ring-ring p-1">
variant="default" <ChatInput
size="sm"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
setShowAddImage(!showAddImage);
}}
>
Image
</Button>
{showAddImage && (
<AddImage
chatStore={chatStore}
setChatStore={setChatStore}
setShowAddImage={setShowAddImage}
images={images}
setImages={setImages}
/>
)}
<Textarea
autoFocus
value={inputMsg} value={inputMsg}
ref={userInputRef} ref={userInputRef}
placeholder="Type your message here..."
onChange={(event: any) => { onChange={(event: any) => {
setInputMsg(event.target.value); setInputMsg(event.target.value);
autoHeight(event.target); autoHeight(event.target);
@@ -735,15 +713,33 @@ export default function ChatBOX(props: {
autoHeight(event.target); autoHeight(event.target);
setInputMsg(event.target.value); setInputMsg(event.target.value);
}} }}
className="min-h-[40px] flex-grow resize-none" className="min-h-12 resize-none rounded-lg bg-background border-0 p-3 shadow-none focus-visible:ring-0"
placeholder="Type here..."
style={{
lineHeight: "1.39",
}}
/> />
<div className="flex items-center p-3 pt-0">
<Button
variant="ghost"
size="icon"
onClick={() => setShowAddImage(!showAddImage)}
disabled={showGenerating || !chatStore.apiKey}
>
<ImageIcon className="size-4" />
<span className="sr-only">Add Image</span>
</Button>
{chatStore.whisper_api && chatStore.whisper_key && (
<Button variant="ghost" size="icon">
<WhisperButton
chatStore={chatStore}
inputMsg={inputMsg}
setInputMsg={setInputMsg}
/>
<span className="sr-only">Use Microphone</span>
</Button>
)}
<Button <Button
variant="default"
size="sm" size="sm"
className="ml-auto gap-1.5"
disabled={showGenerating} disabled={showGenerating}
onClick={() => { onClick={() => {
send(inputMsg, true); send(inputMsg, true);
@@ -751,69 +747,19 @@ export default function ChatBOX(props: {
autoHeight(userInputRef.current); autoHeight(userInputRef.current);
}} }}
> >
{Tr("Send")} Send Message
<CornerDownLeftIcon className="size-3.5" />
</Button> </Button>
{chatStore.whisper_api && chatStore.whisper_key && ( </div>
<WhisperButton </form>
chatStore={chatStore}
inputMsg={inputMsg} {showAddImage && (
setInputMsg={setInputMsg} <AddImage
/>
)}
{chatStore.develop_mode && (
<Button
variant="outline"
size="sm"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
chatStore.history.push({
role: "assistant",
content: inputMsg,
token:
calculate_token_length(inputMsg) +
calculate_token_length(images),
hide: false,
example: false,
audio: null,
logprobs: null,
response_model_name: null,
});
setInputMsg("");
setChatStore({ ...chatStore });
}}
>
{Tr("AI")}
</Button>
)}
{chatStore.develop_mode && (
<Button
variant="outline"
size="sm"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
send(inputMsg, false);
}}
>
{Tr("User")}
</Button>
)}
{chatStore.develop_mode && (
<Button
variant="outline"
size="sm"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
setShowAddToolMsg(true);
}}
>
{Tr("Tool")}
</Button>
)}
{showAddToolMsg && (
<AddToolMsg
chatStore={chatStore} chatStore={chatStore}
setChatStore={setChatStore} setChatStore={setChatStore}
setShowAddToolMsg={setShowAddToolMsg} setShowAddImage={setShowAddImage}
images={images}
setImages={setImages}
/> />
)} )}
</div> </div>