feat: enhance ListAPIs component with shortLabel prop for improved display and update translations for new chat session prompts

This commit is contained in:
ecwu
2025-01-04 23:13:58 +08:00
parent 1f9c75b91e
commit 236d48e72d
3 changed files with 51 additions and 70 deletions

View File

@@ -14,18 +14,20 @@ import { AppContext } from "./pages/App";
interface Props { interface Props {
label: string; label: string;
shortLabel: string;
apiField: string; apiField: string;
keyField: string; keyField: string;
} }
export function ListAPIs({ label, apiField, keyField }: Props) { export function ListAPIs({ label, shortLabel, apiField, keyField }: Props) {
const ctx = useContext(AppContext); const ctx = useContext(AppContext);
if (ctx === null) return <></>; if (ctx === null) return <></>;
return ( return (
<NavigationMenuItem> <NavigationMenuItem>
<NavigationMenuTrigger> <NavigationMenuTrigger>
{label}{" "} <span className="lg:hidden">{shortLabel}</span>
<span className="hidden lg:inline"> <span className="hidden lg:inline">
{label}{" "}
{ctx.templateAPIs.find( {ctx.templateAPIs.find(
(t) => (t) =>
ctx.chatStore[apiField as keyof ChatStore] === t.endpoint && ctx.chatStore[apiField as keyof ChatStore] === t.endpoint &&

View File

@@ -1,8 +1,7 @@
import { IDBPDatabase } from "idb";
import { useContext, useRef } from "react"; import { useContext, useRef } from "react";
import { useEffect, useState, Dispatch } from "react"; import { useEffect, useState } from "react";
import { Tr, langCodeContext, LANG_OPTIONS } from "@/translate"; import { Tr } from "@/translate";
import { addTotalCost, getTotalCost } from "@/utils/totalCost"; import { addTotalCost } from "@/utils/totalCost";
import ChatGPT, { import ChatGPT, {
calculate_token_length, calculate_token_length,
FetchResponse, FetchResponse,
@@ -12,30 +11,19 @@ import ChatGPT, {
Logprobs, Logprobs,
Usage, Usage,
} from "@/chatgpt"; } from "@/chatgpt";
import { import { ChatStoreMessage } from "../types/chatstore";
ChatStore,
ChatStoreMessage,
TemplateChatStore,
TemplateAPI,
TemplateTools,
} from "../types/chatstore";
import Message from "@/message"; import Message from "@/message";
import { models } from "@/types/models"; import { models } from "@/types/models";
import { AddImage } from "@/addImage"; import { AddImage } from "@/addImage";
import { ListAPIs } from "@/listAPIs"; import { ListAPIs } from "@/listAPIs";
import { ListToolsTemplates } from "@/listToolsTemplates"; import { ListToolsTemplates } from "@/listToolsTemplates";
import { autoHeight } from "@/utils/textAreaHelp"; import { autoHeight } from "@/utils/textAreaHelp";
import Templates from "@/components/Templates";
import VersionHint from "@/components/VersionHint"; import VersionHint from "@/components/VersionHint";
import WhisperButton from "@/components/WhisperButton"; import WhisperButton from "@/components/WhisperButton";
import AddToolMsg from "./AddToolMsg";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ChatInput } from "@/components/ui/chat/chat-input"; import { ChatInput } from "@/components/ui/chat/chat-input";
import { import {
ChatBubble, ChatBubble,
ChatBubbleAvatar,
ChatBubbleMessage, ChatBubbleMessage,
ChatBubbleAction, ChatBubbleAction,
ChatBubbleActionWrapper, ChatBubbleActionWrapper,
@@ -43,33 +31,22 @@ import {
import { ChatMessageList } from "@/components/ui/chat/chat-message-list"; import { ChatMessageList } from "@/components/ui/chat/chat-message-list";
import { import {
AlertTriangleIcon, ArrowDownToDotIcon,
ArrowUpIcon,
CornerDownLeftIcon, CornerDownLeftIcon,
CornerLeftUpIcon, CornerLeftUpIcon,
CornerUpLeftIcon, CornerRightUpIcon,
GlobeIcon,
ImageIcon, ImageIcon,
InfoIcon, InfoIcon,
KeyIcon, ScissorsIcon,
SearchIcon,
Settings2,
Settings2Icon,
} from "lucide-react"; } from "lucide-react";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { import {
NavigationMenu, NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList, NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu"; } from "@/components/ui/navigation-menu";
import { AppContext } from "./App"; import { AppContext } from "./App";
import { addToRange } from "react-day-picker";
export default function ChatBOX() { export default function ChatBOX() {
const ctx = useContext(AppContext); const ctx = useContext(AppContext);
@@ -428,21 +405,33 @@ export default function ChatBOX() {
<NavigationMenu> <NavigationMenu>
<NavigationMenuList> <NavigationMenuList>
{ctx.templateAPIs.length > 0 && ( {ctx.templateAPIs.length > 0 && (
<ListAPIs label="API" apiField="apiEndpoint" keyField="apiKey" /> <ListAPIs
label="Chat API"
shortLabel="API"
apiField="apiEndpoint"
keyField="apiKey"
/>
)} )}
{ctx.templateAPIsWhisper.length > 0 && ( {ctx.templateAPIsWhisper.length > 0 && (
<ListAPIs <ListAPIs
label="Whisper API" label="Whisper API"
shortLabel="Whisper"
apiField="whisper_api" apiField="whisper_api"
keyField="whisper_key" keyField="whisper_key"
/> />
)} )}
{ctx.templateAPIsTTS.length > 0 && ( {ctx.templateAPIsTTS.length > 0 && (
<ListAPIs label="TTS API" apiField="tts_api" keyField="tts_key" /> <ListAPIs
label="TTS API"
shortLabel="TTS"
apiField="tts_api"
keyField="tts_key"
/>
)} )}
{ctx.templateAPIsImageGen.length > 0 && ( {ctx.templateAPIsImageGen.length > 0 && (
<ListAPIs <ListAPIs
label="Image Gen API" label="Image Gen API"
shortLabel="ImgGen"
apiField="image_gen_api" apiField="image_gen_api"
keyField="image_gen_key" keyField="image_gen_key"
/> />
@@ -453,52 +442,31 @@ export default function ChatBOX() {
</div> </div>
<div className="grow flex flex-col p-2 w-full"> <div className="grow flex flex-col p-2 w-full">
<ChatMessageList> <ChatMessageList>
{chatStore.history.filter((msg) => !msg.example).length == 0 && (
<div className="bg-base-200 break-all p-3 my-3 text-left">
<h2>
<span>{Tr("Saved prompt templates")}</span>
<Button
variant="link"
className="mx-2"
onClick={() => {
chatStore.systemMessageContent = "";
chatStore.toolsString = "";
chatStore.history = [];
setChatStore({ ...chatStore });
}}
>
{Tr("Reset Current")}
</Button>
</h2>
<div className="divider"></div>
<div className="flex flex-wrap">
<Templates />
</div>
</div>
)}
{chatStore.history.length === 0 && ( {chatStore.history.length === 0 && (
<Alert variant="default" className="my-3"> <Alert variant="default" className="my-3">
<InfoIcon className="h-4 w-4" /> <InfoIcon className="h-4 w-4" />
<AlertTitle>{Tr("No chat history here")}</AlertTitle> <AlertTitle>
{Tr("This is a new chat session, start by typing a message")}
</AlertTitle>
<AlertDescription className="flex flex-col gap-1 mt-5"> <AlertDescription className="flex flex-col gap-1 mt-5">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Settings2Icon className="h-4 w-4" /> <CornerRightUpIcon className="h-4 w-4" />
<span> <span>
{Tr("Model")}: {chatStore.model} {Tr(
</span> "Settings button located at the top right corner can be used to change the settings of this chat"
</div> )}
<div className="flex items-center gap-2">
<ArrowUpIcon className="h-4 w-4" />
<span>
{Tr("Click above to change the settings of this chat")}
</span> </span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<CornerLeftUpIcon className="h-4 w-4" /> <CornerLeftUpIcon className="h-4 w-4" />
<span>{Tr("Click the corner to create a new chat")}</span> <span>
{Tr(
"'New' button located at the top left corner can be used to create a new chat"
)}
</span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<AlertTriangleIcon className="h-4 w-4" /> <ArrowDownToDotIcon className="h-4 w-4" />
<span> <span>
{Tr( {Tr(
"All chat history and settings are stored in the local browser" "All chat history and settings are stored in the local browser"
@@ -525,8 +493,13 @@ export default function ChatBOX() {
<ChatBubbleActionWrapper> <ChatBubbleActionWrapper>
<ChatBubbleAction <ChatBubbleAction
className="size-7" className="size-7"
icon={<Settings2Icon className="size-4" />} icon={<ScissorsIcon className="size-4" />}
// TODO: add a button to show settings onClick={() => {
chatStore.systemMessageContent = "";
chatStore.toolsString = "";
chatStore.history = [];
setChatStore({ ...chatStore });
}}
/> />
</ChatBubbleActionWrapper> </ChatBubbleActionWrapper>
</ChatBubble> </ChatBubble>

View File

@@ -14,6 +14,12 @@ const LANG_MAP: Record<string, string> = {
"saved api templates": "已保存的 API 模板", "saved api templates": "已保存的 API 模板",
"saved prompt templates": "已保存的提示模板", "saved prompt templates": "已保存的提示模板",
"no chat history here": "暂无历史对话记录", "no chat history here": "暂无历史对话记录",
"This is a new chat session, start by typing a message":
"这是一个新对话,开始输入消息",
"Settings button located at the top right corner can be used to change the settings of this chat":
"右上角的设置按钮可用于更改此对话的设置",
"'New' button located at the top left corner can be used to create a new chat":
"左上角的 '新' 按钮可用于创建新对话",
"click above to change the settings of this chat": "click above to change the settings of this chat":
"点击上方更改此对话的参数(请勿泄漏)", "点击上方更改此对话的参数(请勿泄漏)",
"click the NEW to create a new chat": "点击左上角 NEW 新建对话", "click the NEW to create a new chat": "点击左上角 NEW 新建对话",