feat(components): 新增图标组件并优化历史记录功能
- 新增 Bell、Collect 和 NotCollect 图标组件 - 优化 History 组件,添加隐藏 logo 功能 - 调整 Message 组件样式,移除不必要的代码 - 更新 Scene 组件 Header 颜色 - 注释掉 tailwind.css 中的 arimo 字体权重
This commit is contained in:
@@ -24,11 +24,12 @@ export const PlaygroundEmpty = () => {
|
||||
<div className="w-full pb-4 pt-[20%] grid grid-cols-3 gap-3">
|
||||
{qaPrompt.map((item, index) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="p-6 bg-gradient-to-br from-blue-50/90 via-indigo-50/90 to-purple-50/90 backdrop-blur-xl border border-white/60 shadow-xl rounded-2xl cursor-pointer hover:shadow-blue-200/40 hover:from-blue-100/90 hover:to-indigo-100/90 transition-all duration-500 hover:-translate-y-1"
|
||||
onClick={() => handleQuestion(item.title)}>
|
||||
<div className="flex items-center">
|
||||
<div className="text-blue-500 mr-2 w-10">{item.icon}</div>
|
||||
<div className="font-medium text-sm text-gray-800">
|
||||
<div className="text-sm text-gray-800">
|
||||
{item.title}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ import { defaultEmbeddingModelForRag } from "~/services/ollama"
|
||||
import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react"
|
||||
import { getVariable } from "@/utils/select-variable"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect"
|
||||
// import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect"
|
||||
import { useSpeechRecognition } from "@/hooks/useSpeechRecognition"
|
||||
import { PiGlobe, PiNetwork } from "react-icons/pi"
|
||||
import { handleChatInputKeyDown } from "@/utils/key-down"
|
||||
@@ -369,11 +369,15 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
variant="filled"
|
||||
size="large"
|
||||
className="w-full mt-4 hover:!bg-[#0057ff1a]"
|
||||
style={iodSearch ? {
|
||||
color: "#0057ff",
|
||||
background: "#0057ff0f",
|
||||
border: "1px solid #0066ff26"
|
||||
} : {}}>
|
||||
style={
|
||||
iodSearch
|
||||
? {
|
||||
color: "#0057ff",
|
||||
background: "#0057ff0f",
|
||||
border: "1px solid #0066ff26"
|
||||
}
|
||||
: {}
|
||||
}>
|
||||
<PiNetwork className="h-5 w-5" />
|
||||
数联网深度搜索{iodSearch ? ":开" : ""}
|
||||
</Button>
|
||||
@@ -381,34 +385,32 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex !justify-end gap-3">
|
||||
<div className="flex !justify-end gap-1">
|
||||
{!selectedKnowledge && (
|
||||
<Tooltip title={t("tooltip.uploadImage")}>
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
onClick={() => {
|
||||
inputRef.current?.click()
|
||||
}}
|
||||
className={`flex items-center justify-center dark:text-gray-300 ${
|
||||
className={`!px-[5px] flex items-center justify-center dark:text-gray-300 ${
|
||||
chatMode === "rag" ? "hidden" : "block"
|
||||
}`}>
|
||||
<ImageIcon className="h-5 w-5" />
|
||||
</button>
|
||||
<ImageIcon stroke-width={1} className="h-5 w-5" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
{browserSupportsSpeechRecognition && (
|
||||
<Tooltip title={t("tooltip.speechToText")}>
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
color="default"
|
||||
variant="text"
|
||||
onClick={async () => {
|
||||
if (isListening) {
|
||||
stopSpeechRecognition()
|
||||
} else {
|
||||
console.log(
|
||||
"开始语音识别,语言:",
|
||||
speechToTextLanguage
|
||||
)
|
||||
resetTranscript()
|
||||
startListening({
|
||||
continuous: true,
|
||||
@@ -416,40 +418,43 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
})
|
||||
}
|
||||
}}
|
||||
className={`flex items-center justify-center dark:text-gray-300`}>
|
||||
className={`flex items-center justify-center dark:text-gray-300 !px-[5px]`}>
|
||||
{!isListening ? (
|
||||
<MicIcon className="h-5 w-5" />
|
||||
<MicIcon stroke-width={1} className="h-5 w-5" />
|
||||
) : (
|
||||
<div className="relative">
|
||||
<span className="animate-ping absolute inline-flex h-3 w-3 rounded-full bg-red-400 opacity-75"></span>
|
||||
<MicIcon className="h-5 w-5" />
|
||||
<MicIcon
|
||||
stroke-width={1}
|
||||
className="h-5 w-5"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
<KnowledgeSelect />
|
||||
{/*<KnowledgeSelect />*/}
|
||||
|
||||
{!isSending ? (
|
||||
<Dropdown.Button
|
||||
type="default"
|
||||
htmlType="submit"
|
||||
disabled={isSending}
|
||||
className="!justify-end !w-auto"
|
||||
icon={
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-5 h-5">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="m19.5 8.25-7.5 7.5-7.5-7.5"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
// icon={
|
||||
// <svg
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// fill="none"
|
||||
// viewBox="0 0 24 24"
|
||||
// strokeWidth={1.5}
|
||||
// stroke="currentColor"
|
||||
// className="w-5 h-5">
|
||||
// <path
|
||||
// strokeLinecap="round"
|
||||
// strokeLinejoin="round"
|
||||
// d="m19.5 8.25-7.5 7.5-7.5-7.5"
|
||||
// />
|
||||
// </svg>
|
||||
// }
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
@@ -479,20 +484,6 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
]
|
||||
}}>
|
||||
<div className="inline-flex gap-2">
|
||||
{sendWhenEnter ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
className="h-5 w-5"
|
||||
viewBox="0 0 24 24">
|
||||
<path d="M9 10L4 15 9 20"></path>
|
||||
<path d="M20 4v7a4 4 0 01-4 4H4"></path>
|
||||
</svg>
|
||||
) : null}
|
||||
{t("common:submit")}
|
||||
</div>
|
||||
</Dropdown.Button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext, useState } from "react"
|
||||
import React, { createContext, useContext, useMemo, useState } from "react"
|
||||
|
||||
import { AnimatePresence, motion } from "framer-motion"
|
||||
|
||||
@@ -8,6 +8,8 @@ import { PlaygroundScene } from "@/components/Common/Playground/Scene.tsx"
|
||||
import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx"
|
||||
import { Card } from "antd"
|
||||
import { CloseOutlined } from "@ant-design/icons"
|
||||
import { useMessageOption } from "@/hooks/useMessageOption.tsx"
|
||||
import { Message } from "@/types/message.ts"
|
||||
|
||||
// 定义 Context 类型
|
||||
interface IodPlaygroundContextType {
|
||||
@@ -17,6 +19,7 @@ interface IodPlaygroundContextType {
|
||||
setDetailHeader: React.Dispatch<React.SetStateAction<React.ReactNode>>
|
||||
detailMain: React.ReactNode
|
||||
setDetailMain: React.Dispatch<React.SetStateAction<React.ReactNode>>
|
||||
currentMessage: Message | null
|
||||
}
|
||||
|
||||
// 创建 Context
|
||||
@@ -36,13 +39,41 @@ export const useIodPlaygroundContext = () => {
|
||||
}
|
||||
|
||||
export const PlaygroundIod = () => {
|
||||
const { messages, iodLoading, currentMessageId, iodSearch } =
|
||||
useMessageOption()
|
||||
|
||||
const [showPlayground, setShowPlayground] = useState<boolean>(true)
|
||||
const [detailHeader, setDetailHeader] = useState(<></>)
|
||||
const [detailMain, setDetailMain] = useState(<></>)
|
||||
|
||||
const currentMessage = useMemo<Message | null>(() => {
|
||||
if (iodLoading) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (messages.length && iodSearch) {
|
||||
// 如果不存在currentMessageId默认返回最后一个message
|
||||
if (!currentMessageId) {
|
||||
return messages.at(-1)
|
||||
}
|
||||
|
||||
const currentMessage = messages?.find(
|
||||
(message) => message.id === currentMessageId
|
||||
)
|
||||
if (currentMessage) {
|
||||
return currentMessage
|
||||
}
|
||||
// 如果当前message不存在最后一个message
|
||||
return messages.at(-1)
|
||||
}
|
||||
|
||||
return null
|
||||
}, [currentMessageId, messages, iodLoading, iodSearch])
|
||||
|
||||
return (
|
||||
<PlaygroundContext.Provider
|
||||
value={{
|
||||
currentMessage,
|
||||
showPlayground,
|
||||
setShowPlayground,
|
||||
detailMain,
|
||||
@@ -65,7 +96,6 @@ const PlaygroundContent = () => {
|
||||
const { showPlayground, detailMain, detailHeader, setShowPlayground } =
|
||||
useIodPlaygroundContext()
|
||||
|
||||
|
||||
return (
|
||||
<AnimatePresence mode="popLayout">
|
||||
{showPlayground ? (
|
||||
@@ -80,7 +110,9 @@ const PlaygroundContent = () => {
|
||||
}}
|
||||
className="h-full grid grid-rows-12 gap-3">
|
||||
<div className="w-full row-span-5">
|
||||
<PlaygroundIodRelevant className={classNames.replace('!bg-[rgba(240,245,255,0.3)]', '')} />
|
||||
<PlaygroundIodRelevant
|
||||
className={classNames.replace("!bg-[rgba(240,245,255,0.3)]", "")}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full row-span-4 grid grid-cols-2 gap-3 custom-scrollbar">
|
||||
<PlaygroundData className={classNames} />
|
||||
|
||||
Reference in New Issue
Block a user