Commit a98cce0d by HoMeTown

feat: 历史记录的检索

parent 52f6026a
...@@ -17,6 +17,7 @@ export const HistoryBar: React.FC<HistoryBarProps> = ({ isVisible }) => { ...@@ -17,6 +17,7 @@ export const HistoryBar: React.FC<HistoryBarProps> = ({ isVisible }) => {
const showToast = useToast() const showToast = useToast()
const [isOpenConversationModal, setIsOpenConversationModal] = useState(false) const [isOpenConversationModal, setIsOpenConversationModal] = useState(false)
const { conversations } = useAppSelector(state => state.conversation) const { conversations } = useAppSelector(state => state.conversation)
const [searchValue, setSearchValue] = useState('')
const handleOpen = () => { const handleOpen = () => {
if (conversations.length === 0) { if (conversations.length === 0) {
...@@ -39,10 +40,10 @@ export const HistoryBar: React.FC<HistoryBarProps> = ({ isVisible }) => { ...@@ -39,10 +40,10 @@ export const HistoryBar: React.FC<HistoryBarProps> = ({ isVisible }) => {
> >
<div className="pt-[24px] flex flex-col h-full"> <div className="pt-[24px] flex flex-col h-full">
<div className="px-[32px] h-[40px]"> <div className="px-[32px] h-[40px]">
<Input classNames={{ inputWrapper: ['bg-white', 'data-[hover=true]:bg-[#fff]', 'group-data-[focus=true]:bg-white', 'rounded-[24px]'] }} placeholder="搜索历史记录" startContent={<SearchIcon />} /> <Input value={searchValue} onValueChange={setSearchValue} classNames={{ inputWrapper: ['bg-white', 'data-[hover=true]:bg-[#fff]', 'group-data-[focus=true]:bg-white', 'rounded-[24px]'] }} placeholder="搜索历史记录" startContent={<SearchIcon />} />
</div> </div>
<div className="px-[32px] flex-1 overflow-y-auto"> <div className="px-[32px] flex-1 overflow-y-auto scrollbar-hide">
<HistoryBarList /> <HistoryBarList searchValue={searchValue} />
</div> </div>
<div className="text-[12px] border-t-solid border-t-[1px] border-t-[#82969C12] w-full h-[48px] flex items-center justify-center"> <div className="text-[12px] border-t-solid border-t-[1px] border-t-[#82969C12] w-full h-[48px] flex items-center justify-center">
<Button onClick={handleOpen} className="w-full" color="primary" variant="light" startContent={<HistoryMenuIcon />}> <Button onClick={handleOpen} className="w-full" color="primary" variant="light" startContent={<HistoryMenuIcon />}>
......
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Button } from '@nextui-org/react' import { Button } from '@nextui-org/react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useEffect, useState } from 'react'
import { useDebounceFn } from 'ahooks'
import { containerVariants, itemVariants } from '../../motionAnimate' import { containerVariants, itemVariants } from '../../motionAnimate'
import EmptyIcon from '@/assets/svg/empty.svg?react' import EmptyIcon from '@/assets/svg/empty.svg?react'
import { useAppSelector } from '@/store/hook' import { useAppSelector } from '@/store/hook'
import type { Conversation } from '@/types/conversation' import type { Conversation } from '@/types/conversation'
import { processConversationData } from '@/store/conversationSlice.helper'
export const HistoryBarList: React.FC = () => { interface HistoryBarListProps {
searchValue: string
}
export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue }) => {
const navigate = useNavigate() const navigate = useNavigate()
const { currentConversationId, conversations } = useAppSelector(state => state.conversation) const { currentConversationId, conversations } = useAppSelector(state => state.conversation)
const [allItems, setAllItems] = useState<Conversation[]>([])
const handleClick = (conversation: Conversation) => { const handleClick = (conversation: Conversation) => {
navigate(`/chat/${conversation.conversationId}`) navigate(`/chat/${conversation.conversationId}`)
} }
const handleFilter = useDebounceFn(() => {
const _allItems = conversations.filter(item => item.conversationTitle.includes(searchValue))
setAllItems(processConversationData(_allItems))
}, { wait: 300 })
useEffect(() => {
handleFilter.run()
}, [searchValue])
return ( return (
conversations.length !== 0 allItems.length !== 0
? ( ? (
<motion.ul <motion.ul
variants={containerVariants} variants={containerVariants}
...@@ -22,7 +40,7 @@ export const HistoryBarList: React.FC = () => { ...@@ -22,7 +40,7 @@ export const HistoryBarList: React.FC = () => {
className="w-full flex flex-col gap-[6px]" className="w-full flex flex-col gap-[6px]"
> >
{ {
conversations.map((item, index) => ( allItems.map((item, index) => (
<motion.li <motion.li
key={`${item.conversationId}-${index}`} key={`${item.conversationId}-${index}`}
custom={index} custom={index}
......
...@@ -53,7 +53,7 @@ export const itemVariants = { ...@@ -53,7 +53,7 @@ export const itemVariants = {
y: 0, y: 0,
scale: 1, scale: 1,
transition: { transition: {
delay: i * 0.05, delay: i * 0.03,
type: 'spring', type: 'spring',
stiffness: 200, stiffness: 200,
damping: 20, damping: 20,
......
...@@ -11,14 +11,14 @@ interface UserProps { ...@@ -11,14 +11,14 @@ interface UserProps {
export const UserLogin: React.FC<UserProps> = ({ onLogout }) => { export const UserLogin: React.FC<UserProps> = ({ onLogout }) => {
const { logout } = useAuth() const { logout } = useAuth()
const items = [ const items = [
{ // {
key: 'conact', // key: 'conact',
label: '联系我们', // label: '联系我们',
}, // },
{ // {
key: 'file', // key: 'file',
label: '相关协议', // label: '相关协议',
}, // },
{ {
key: 'logout', key: 'logout',
label: '退出登录', label: '退出登录',
......
...@@ -6,7 +6,6 @@ import LikeIcon from '@/assets/svg/zan.svg?react' ...@@ -6,7 +6,6 @@ import LikeIcon from '@/assets/svg/zan.svg?react'
import UnLikeIcon from '@/assets/svg/cai.svg?react' import UnLikeIcon from '@/assets/svg/cai.svg?react'
import CopyIcon from '@/assets/svg/copy.svg?react' import CopyIcon from '@/assets/svg/copy.svg?react'
import CollectIcon from '@/assets/svg/shouc.svg?react' import CollectIcon from '@/assets/svg/shouc.svg?react'
import ReloadIcon from '@/assets/svg/sx.svg?react'
import LikeIconA from '@/assets/svg/zanA.svg?react' import LikeIconA from '@/assets/svg/zanA.svg?react'
import UnLikeIconA from '@/assets/svg/caiA.svg?react' import UnLikeIconA from '@/assets/svg/caiA.svg?react'
import CollectIconA from '@/assets/svg/shoucA.svg?react' import CollectIconA from '@/assets/svg/shoucA.svg?react'
...@@ -120,9 +119,9 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer }) ...@@ -120,9 +119,9 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
</Button> </Button>
</Tooltip> </Tooltip>
{/* 重新生成 */} {/* 重新生成 */}
<Tooltip color="foreground" content="重新生成" className="capitalize"> {/* <Tooltip color="foreground" content="重新生成" className="capitalize">
<Button variant="light" isIconOnly aria-label="ReloadIcon"><ReloadIcon /></Button> <Button variant="light" isIconOnly aria-label="ReloadIcon"><ReloadIcon /></Button>
</Tooltip> </Tooltip> */}
<UnLikeModal answer={answer} isOpen={isOpenUnLikeModal} onClose={handleClose} /> <UnLikeModal answer={answer} isOpen={isOpenUnLikeModal} onClose={handleClose} />
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment