mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
refactor: nav and search.
feat: use recoil to replace redux feat: use react-native THIS IS NOT FINISHED. DONT USE THIS
This commit is contained in:
parent
d8ccc5b870
commit
af3d74b104
33 changed files with 1142 additions and 473 deletions
|
|
@ -6,67 +6,121 @@ import Pages from '../Conversations/Pages';
|
|||
import Conversations from '../Conversations';
|
||||
import NavLinks from './NavLinks';
|
||||
import { searchFetcher, swr } from '~/utils/fetchers';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { setConvos, setNewConvo, refreshConversation } from '~/store/convoSlice';
|
||||
import { setMessages } from '~/store/messageSlice';
|
||||
import { setDisabled } from '~/store/submitSlice';
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
import store from '~/store';
|
||||
|
||||
export default function Nav({ navVisible, setNavVisible }) {
|
||||
const dispatch = useDispatch();
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
const [isFetching, setIsFetching] = useState(false);
|
||||
|
||||
const containerRef = useRef(null);
|
||||
const scrollPositionRef = useRef(null);
|
||||
|
||||
// const dispatch = useDispatch();
|
||||
const [conversations, setConversations] = useState([]);
|
||||
// current page
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
// total pages
|
||||
const [pages, setPages] = useState(1);
|
||||
const [pageNumber, setPage] = useState(1);
|
||||
const { search, query } = useSelector((state) => state.search);
|
||||
const { conversationId, convos, refreshConvoHint } = useSelector((state) => state.convo);
|
||||
|
||||
|
||||
// search
|
||||
const searchQuery = useRecoilValue(store.searchQuery);
|
||||
const isSearchEnabled = useRecoilValue(store.isSearchEnabled);
|
||||
const isSearching = useRecoilValue(store.isSearching);
|
||||
const { newConversation } = store.useConversation();
|
||||
|
||||
// current conversation
|
||||
const conversation = useRecoilValue(store.conversation);
|
||||
const { conversationId } = conversation || {};
|
||||
const setMessages = useSetRecoilState(store.messages);
|
||||
|
||||
// refreshConversationsHint is used for other components to ask refresh of Nav
|
||||
const refreshConversationsHint = useRecoilValue(store.refreshConversationsHint);
|
||||
|
||||
const { refreshConversations } = store.useConversations();
|
||||
|
||||
const [isFetching, setIsFetching] = useState(false);
|
||||
|
||||
const onSuccess = (data, searchFetch = false) => {
|
||||
if (search) {
|
||||
if (isSearching) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { conversations, pages } = data;
|
||||
let { conversations, pages } = data;
|
||||
if (pageNumber > pages) {
|
||||
setPage(pages);
|
||||
setPageNumber(pages);
|
||||
} else {
|
||||
dispatch(setConvos({ convos: conversations, searchFetch }));
|
||||
if (!searchFetch)
|
||||
conversations = conversations.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
||||
setConversations(conversations);
|
||||
setPages(pages);
|
||||
}
|
||||
};
|
||||
|
||||
const onSearchSuccess = (data, expectedPage) => {
|
||||
const res = data;
|
||||
dispatch(setConvos({ convos: res.conversations, searchFetch: true }));
|
||||
setConversations(res.conversations);
|
||||
if (expectedPage) {
|
||||
setPage(expectedPage);
|
||||
setPageNumber(expectedPage);
|
||||
}
|
||||
setPage(res.pageNumber);
|
||||
setPageNumber(res.pageNumber);
|
||||
setPages(res.pages);
|
||||
setIsFetching(false);
|
||||
if (res.messages?.length > 0) {
|
||||
dispatch(setMessages(res.messages));
|
||||
dispatch(setDisabled(true));
|
||||
setMessages(res.messages);
|
||||
// dispatch(setDisabled(true));
|
||||
}
|
||||
};
|
||||
|
||||
const fetch = useCallback(_.partialRight(searchFetcher.bind(null, () => setIsFetching(true)), onSearchSuccess), [dispatch]);
|
||||
// TODO: dont need this
|
||||
const fetch = useCallback(
|
||||
_.partialRight(
|
||||
searchFetcher.bind(null, () => setIsFetching(true)),
|
||||
onSearchSuccess
|
||||
),
|
||||
[setIsFetching]
|
||||
);
|
||||
|
||||
const clearSearch = () => {
|
||||
setPage(1);
|
||||
dispatch(refreshConversation());
|
||||
if (!conversationId) {
|
||||
dispatch(setNewConvo());
|
||||
dispatch(setMessages([]));
|
||||
setPageNumber(1);
|
||||
refreshConversations();
|
||||
if (conversationId == 'search') {
|
||||
newConversation();
|
||||
}
|
||||
dispatch(setDisabled(false));
|
||||
// dispatch(setDisabled(false));
|
||||
};
|
||||
|
||||
const { data, isLoading, mutate } = swr(`/api/convos?pageNumber=${pageNumber}`, onSuccess, {
|
||||
revalidateOnMount: false,
|
||||
revalidateOnMount: false
|
||||
});
|
||||
|
||||
const containerRef = useRef(null);
|
||||
const scrollPositionRef = useRef(null);
|
||||
const nextPage = async () => {
|
||||
moveToTop();
|
||||
|
||||
if (!isSearching) {
|
||||
setPageNumber(prev => prev + 1);
|
||||
await mutate();
|
||||
} else {
|
||||
await fetch(searchQuery, +pageNumber + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const previousPage = async () => {
|
||||
moveToTop();
|
||||
|
||||
if (!isSearching) {
|
||||
setPageNumber(prev => prev - 1);
|
||||
await mutate();
|
||||
} else {
|
||||
await fetch(searchQuery, +pageNumber - 1);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSearching) {
|
||||
mutate();
|
||||
}
|
||||
}, [pageNumber, conversationId, refreshConversationsHint]);
|
||||
|
||||
const moveToTop = () => {
|
||||
const container = containerRef.current;
|
||||
|
|
@ -75,35 +129,7 @@ export default function Nav({ navVisible, setNavVisible }) {
|
|||
}
|
||||
};
|
||||
|
||||
const nextPage = async () => {
|
||||
moveToTop();
|
||||
|
||||
if (!search) {
|
||||
setPage((prev) => prev + 1);
|
||||
await mutate();
|
||||
} else {
|
||||
await fetch(query, +pageNumber + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const previousPage = async () => {
|
||||
moveToTop();
|
||||
|
||||
if (!search) {
|
||||
setPage((prev) => prev - 1);
|
||||
await mutate();
|
||||
} else {
|
||||
await fetch(query, +pageNumber - 1);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!search) {
|
||||
mutate();
|
||||
}
|
||||
}, [pageNumber, conversationId, refreshConvoHint]);
|
||||
|
||||
useEffect(() => {
|
||||
const moveTo = () => {
|
||||
const container = containerRef.current;
|
||||
|
||||
if (container && scrollPositionRef.current !== null) {
|
||||
|
|
@ -112,18 +138,20 @@ export default function Nav({ navVisible, setNavVisible }) {
|
|||
|
||||
container.scrollTop = Math.min(maxScrollTop, scrollPositionRef.current);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleNavVisible = () => {
|
||||
setNavVisible(prev => !prev);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
moveTo();
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
setNavVisible(false);
|
||||
}, [conversationId]);
|
||||
|
||||
const toggleNavVisible = () => {
|
||||
setNavVisible((prev) => {
|
||||
return !prev;
|
||||
});
|
||||
};
|
||||
|
||||
const containerClasses =
|
||||
isLoading && pageNumber === 1
|
||||
? 'flex flex-col gap-2 text-gray-100 text-sm h-full justify-center items-center'
|
||||
|
|
@ -151,11 +179,11 @@ export default function Nav({ navVisible, setNavVisible }) {
|
|||
>
|
||||
<div className={containerClasses}>
|
||||
{/* {(isLoading && pageNumber === 1) ? ( */}
|
||||
{(isLoading && pageNumber === 1) || (isFetching) ? (
|
||||
{(isLoading && pageNumber === 1) || isFetching ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Conversations
|
||||
conversations={convos}
|
||||
conversations={conversations}
|
||||
conversationId={conversationId}
|
||||
moveToTop={moveToTop}
|
||||
/>
|
||||
|
|
@ -172,6 +200,7 @@ export default function Nav({ navVisible, setNavVisible }) {
|
|||
fetch={fetch}
|
||||
onSearchSuccess={onSearchSuccess}
|
||||
clearSearch={clearSearch}
|
||||
isSearchEnabled={isSearchEnabled}
|
||||
/>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue