From 55aa22a28b63214e2bc3ad93b1bbf9500c773393 Mon Sep 17 00:00:00 2001 From: Jing Hua Date: Sat, 1 Apr 2023 22:45:57 +0800 Subject: [PATCH] feat: search chats / folders fixes #102 --- package.json | 2 ++ src/components/Menu/ChatHistoryList.tsx | 22 +++++++++++-- src/components/Menu/ChatSearch.tsx | 41 +++++++++++++++++++++++++ src/components/SearchBar/SearchBar.tsx | 33 ++++++++++++++++++++ src/components/SearchBar/index.ts | 1 + yarn.lock | 5 +++ 6 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/components/Menu/ChatSearch.tsx create mode 100644 src/components/SearchBar/SearchBar.tsx create mode 100644 src/components/SearchBar/index.ts diff --git a/package.json b/package.json index 4e5ef40..f229338 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "i18next-browser-languagedetector": "^7.0.1", "i18next-http-backend": "^2.1.1", "jspdf": "^2.5.1", + "lodash": "^4.17.21", "match-sorter": "^6.3.1", "papaparse": "^5.4.1", "react": "^18.2.0", @@ -64,6 +65,7 @@ }, "devDependencies": { "@tailwindcss/typography": "^0.5.9", + "@types/lodash": "^4.14.192", "@types/papaparse": "^5.3.7", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", diff --git a/src/components/Menu/ChatHistoryList.tsx b/src/components/Menu/ChatHistoryList.tsx index 45283ac..eaa0a44 100644 --- a/src/components/Menu/ChatHistoryList.tsx +++ b/src/components/Menu/ChatHistoryList.tsx @@ -5,6 +5,7 @@ import { shallow } from 'zustand/shallow'; import NewFolder from './NewFolder'; import ChatFolder from './ChatFolder'; import ChatHistory from './ChatHistory'; +import ChatSearch from './ChatSearch'; import { ChatHistoryInterface, @@ -23,10 +24,13 @@ const ChatHistoryList = () => { const [isHover, setIsHover] = useState(false); const [folders, setFolders] = useState({}); const [noFolders, setNoFolders] = useState([]); + const [filter, setFilter] = useState(''); + const chatsRef = useRef(useStore.getState().chats || []); const foldersNameRef = useRef(useStore.getState().foldersName); + const filterRef = useRef(filter); - const updateFolders = () => { + const updateFolders = useRef(() => { const _folders: ChatHistoryFolderInterface = {}; const _noFolders: ChatHistoryInterface[] = []; const chats = useStore.getState().chats; @@ -36,6 +40,14 @@ const ChatHistoryList = () => { if (chats) { chats.forEach((chat, index) => { + const filterLowerCase = filterRef.current.toLowerCase(); + if ( + !chat.title.toLocaleLowerCase().includes(filterLowerCase) && + !chat.folder?.toLowerCase().includes(filterLowerCase) && + index !== currentChatIndex + ) + return; + if (!chat.folder) { _noFolders.push({ title: chat.title, index: index }); } else { @@ -47,7 +59,7 @@ const ChatHistoryList = () => { setFolders(_folders); setNoFolders(_noFolders); - }; + }).current; useEffect(() => { updateFolders(); @@ -92,6 +104,11 @@ const ChatHistoryList = () => { } }, [currentChatIndex, chatTitles]); + useEffect(() => { + filterRef.current = filter; + updateFolders(); + }, [filter]); + const handleDrop = (e: React.DragEvent) => { if (e.dataTransfer) { e.stopPropagation(); @@ -130,6 +147,7 @@ const ChatHistoryList = () => { onDragEnd={handleDragEnd} > +
{Object.keys(folders).map((folderName, folderIndex) => ( >; +}) => { + const [_filter, _setFilter] = useState(filter); + const generating = useStore((state) => state.generating); + + const handleChange = (e: React.ChangeEvent) => { + _setFilter(e.target.value); + }; + + const debouncedUpdateFilter = useRef( + debounce((f) => { + setFilter(f); + }, 500) + ).current; + + useEffect(() => { + debouncedUpdateFilter(_filter); + }, [_filter]); + + return ( + + ); +}; + +export default ChatSearch; diff --git a/src/components/SearchBar/SearchBar.tsx b/src/components/SearchBar/SearchBar.tsx new file mode 100644 index 0000000..b376969 --- /dev/null +++ b/src/components/SearchBar/SearchBar.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +const SearchBar = ({ + value, + handleChange, + className, + disabled, +}: { + value: string; + handleChange: React.ChangeEventHandler; + className?: React.HTMLAttributes['className']; + disabled?: boolean; +}) => { + const { t } = useTranslation(); + + return ( +
+ { + handleChange(e); + }} + /> +
+ ); +}; + +export default SearchBar; diff --git a/src/components/SearchBar/index.ts b/src/components/SearchBar/index.ts new file mode 100644 index 0000000..e1b1580 --- /dev/null +++ b/src/components/SearchBar/index.ts @@ -0,0 +1 @@ +export { default } from './SearchBar'; diff --git a/yarn.lock b/yarn.lock index 325057d..2fd5492 100644 --- a/yarn.lock +++ b/yarn.lock @@ -582,6 +582,11 @@ dependencies: "@types/node" "*" +"@types/lodash@^4.14.192": + version "4.14.192" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285" + integrity sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A== + "@types/mdast@^3.0.0": version "3.0.10" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"