diff --git a/backend/consts/const.py b/backend/consts/const.py index 2d6817423..003e01057 100644 --- a/backend/consts/const.py +++ b/backend/consts/const.py @@ -287,4 +287,4 @@ class VectorDatabaseType(str, Enum): # APP Version -APP_VERSION = "v1.7.8.1" +APP_VERSION = "v1.7.9" diff --git a/frontend/app/[locale]/chat/components/chatInput.tsx b/frontend/app/[locale]/chat/components/chatInput.tsx index a6595f3d6..dd1d69143 100644 --- a/frontend/app/[locale]/chat/components/chatInput.tsx +++ b/frontend/app/[locale]/chat/components/chatInput.tsx @@ -15,7 +15,7 @@ import { } from "@ant-design/icons"; import { Input } from "@/components/ui/input"; -import { Button } from "@/components/ui/button"; +import { Button } from "antd"; import { Tooltip } from "@/components/ui/tooltip"; import { Textarea } from "@/components/ui/textarea"; import { conversationService } from "@/services/conversationService"; @@ -1034,11 +1034,12 @@ export function ChatInput({ } > + type="text" + size="middle" + className="flex-1 justify-start text-left min-w-0 max-w-[250px] px-3 py-2 h-auto border-0 shadow-none bg-transparent hover:!bg-transparent active:!bg-transparent" + onClick={() => onDialogClick(dialog)} + > + + + {dialog.conversation_title} + + - onDropdownOpenChange( @@ -261,37 +255,49 @@ export function ChatSidebar({ dialog.conversation_id.toString() ) } - > - - - - - + menu={{ + items: [ + { + key: "rename", + label: ( + + + {t("chatLeftSidebar.rename")} + + ), + }, + { + key: "delete", + label: ( + + + {t("chatLeftSidebar.delete")} + + ), + }, + ], + onClick: ({ key }) => { + if (key === "rename") { handleStartEdit( dialog.conversation_id, dialog.conversation_title - ) + ); + } else if (key === "delete") { + handleDeleteClick(dialog.conversation_id); } - > - - {t("chatLeftSidebar.rename")} - - handleDeleteClick(dialog.conversation_id)} - > - - {t("chatLeftSidebar.delete")} - - - + }, + }} + placement="bottomRight" + trigger={["click"]} + > + + )} @@ -309,12 +315,12 @@ export function ChatSidebar({ @@ -325,12 +331,12 @@ export function ChatSidebar({ @@ -353,8 +359,9 @@ export function ChatSidebar({
diff --git a/frontend/app/[locale]/chat/components/chatRightPanel.tsx b/frontend/app/[locale]/chat/components/chatRightPanel.tsx index 1ee4ac473..64be200e0 100644 --- a/frontend/app/[locale]/chat/components/chatRightPanel.tsx +++ b/frontend/app/[locale]/chat/components/chatRightPanel.tsx @@ -2,13 +2,12 @@ import { useState, useEffect, useRef, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { ExternalLink, Database, X, Server } from "lucide-react"; -import { Button } from "@/components/ui/button"; import { StaticScrollArea } from "@/components/ui/scrollArea"; import { ImageItem, ChatRightPanelProps, SearchResult } from "@/types/chat"; import { API_ENDPOINTS } from "@/services/api"; import { formatDate, formatUrl } from "@/lib/utils"; import { convertImageUrlToApiUrl, extractObjectNameFromUrl, storageService } from "@/services/storageService"; -import { message, Tabs } from "antd"; +import { message, Button, Tabs } from "antd"; import log from "@/lib/logger"; @@ -95,10 +94,10 @@ export function ChatRightPanel({ try { // Convert image URL to backend API URL const apiUrl = convertImageUrlToApiUrl(imageUrl); - + // Use backend API to get the image const response = await fetch(apiUrl); - + if (!response.ok) { throw new Error(`Failed to load image: ${response.statusText}`); } @@ -106,12 +105,12 @@ export function ChatRightPanel({ // Get image as blob and convert to base64 const blob = await response.blob(); const reader = new FileReader(); - + reader.onloadend = () => { const base64Data = reader.result as string; // Remove data URL prefix (e.g., "data:image/png;base64,") const base64 = base64Data.split(',')[1] || base64Data; - + setImageData((prev) => ({ ...prev, [imageUrl]: { @@ -123,13 +122,13 @@ export function ChatRightPanel({ })); loadingImages.current.delete(imageUrl); }; - + reader.onerror = () => { log.error("Failed to read image blob"); handleImageLoadFail(imageUrl); loadingImages.current.delete(imageUrl); }; - + reader.readAsDataURL(blob); } catch (error) { log.error(t("chatRightPanel.imageProxyError"), error); @@ -234,7 +233,7 @@ export function ChatRightPanel({ const handleFileDownload = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); - + if (!filename && !url) { message.error(t("chatRightPanel.fileDownloadError", "File name or URL is missing")); return; @@ -481,9 +480,9 @@ export function ChatRightPanel({ >
@@ -353,16 +351,14 @@ export function ChatStreamFinalMessage({ } > @@ -377,16 +373,14 @@ export function ChatStreamFinalMessage({ } > @@ -395,8 +389,6 @@ export function ChatStreamFinalMessage({ {/* Voice playback button */} diff --git a/frontend/app/[locale]/chat/streaming/chatStreamMain.tsx b/frontend/app/[locale]/chat/streaming/chatStreamMain.tsx index ca0331fc3..bb743ba28 100644 --- a/frontend/app/[locale]/chat/streaming/chatStreamMain.tsx +++ b/frontend/app/[locale]/chat/streaming/chatStreamMain.tsx @@ -4,9 +4,8 @@ import { ChevronDown } from "lucide-react"; import { motion, AnimatePresence } from "framer-motion"; import { ScrollArea } from "@/components/ui/scrollArea"; -import { Button } from "@/components/ui/button"; +import { Button } from "antd"; import { ROLE_ASSISTANT } from "@/const/agentConfig"; -import { chatConfig } from "@/const/chatConfig"; import { USER_ROLES } from "@/const/modelConfig"; import { ChatMessageType, ProcessedMessages, ChatStreamMainProps } from "@/types/chat"; @@ -100,7 +99,7 @@ export function ChatStreamMain({ // Handle message classification useEffect(() => { const finalMsgs: ChatMessageType[] = []; - + // Track the latest user message ID for scroll behavior messages.forEach((message) => { if (message.role === USER_ROLES.USER && message.id) { @@ -328,7 +327,7 @@ export function ChatStreamMain({ ) : conversationLoadError ? ( // when conversation load error, show error message
-
+
{t("chatStreamMain.loadError")}
@@ -336,8 +335,7 @@ export function ChatStreamMain({ {conversationLoadError}
) : ( - ) : ( - ) : ( -