🔍 refactor: Search & Message Retrieval (#6903)

* refactor: conversation search fetch

* refactor: Message and Convo fetch with paramters and search

* refactor: update search states and cleanup old store states

* refactor: re-enable search API; fix: search conversation

* fix: message's convo fetch

* fix: redirect when searching

* chore: use logger instead of console

* fix: search message loading

* feat: small optimizations

* feat(Message): remove cache for search path

* fix: handle delete of all archivedConversation and sharedLinks

* chore: cleanup

* fix: search messages

* style: update ConvoOptions styles

* refactor(SearchButtons): streamline conversation fetching and remove unused state

* fix: ensure messages are invalidated after fetching conversation data

* fix: add iconURL to conversation query selection

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
Marco Beretta 2025-04-17 03:07:43 +02:00 committed by GitHub
parent 851938e7a6
commit 88f4ad7c47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 489 additions and 576 deletions

View file

@ -43,7 +43,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
const [isTextAreaFocused, setIsTextAreaFocused] = useState(false);
const [backupBadges, setBackupBadges] = useState<Pick<BadgeItem, 'id'>[]>([]);
const isSearching = useRecoilValue(store.isSearching);
const search = useRecoilValue(store.search);
const SpeechToText = useRecoilValue(store.speechToText);
const TextToSpeech = useRecoilValue(store.textToSpeech);
const chatDirection = useRecoilValue(store.chatDirection);
@ -151,10 +151,10 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
const textValue = useWatch({ control: methods.control, name: 'text' });
useEffect(() => {
if (!isSearching && textAreaRef.current && !disableInputs) {
if (!search.isSearching && textAreaRef.current && !disableInputs) {
textAreaRef.current.focus();
}
}, [isSearching, disableInputs]);
}, [search.isSearching, disableInputs]);
useEffect(() => {
if (textAreaRef.current) {

View file

@ -1,34 +1,63 @@
import { Link } from 'lucide-react';
import type { TMessage } from 'librechat-data-provider';
import { useRecoilValue } from 'recoil';
import { QueryKeys } from 'librechat-data-provider';
import { useQueryClient } from '@tanstack/react-query';
import type { TMessage, TConversation } from 'librechat-data-provider';
import type { InfiniteData } from '@tanstack/react-query';
import type { ConversationCursorData } from '~/utils';
import { useLocalize, useNavigateToConvo } from '~/hooks';
import { findConversationInInfinite } from '~/utils';
import { useSearchContext } from '~/Providers';
import store from '~/store';
export default function SearchButtons({ message }: { message: TMessage }) {
const localize = useLocalize();
const { searchQueryRes } = useSearchContext();
const queryClient = useQueryClient();
const search = useRecoilValue(store.search);
const { navigateWithLastTools } = useNavigateToConvo();
const conversationId = message.conversationId ?? '';
const clickHandler = async (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
if (!conversationId) {
return;
}
let title = message.title ?? '';
let cachedConvo = queryClient.getQueryData<TConversation>([
QueryKeys.conversation,
conversationId,
]);
const convos = queryClient.getQueryData<InfiniteData<ConversationCursorData>>([
QueryKeys.allConversations,
{ search: search.debouncedQuery },
]);
if (!cachedConvo && convos) {
cachedConvo = findConversationInInfinite(convos, conversationId);
}
if (!title) {
title = cachedConvo?.title ?? '';
}
document.title = title;
navigateWithLastTools(
cachedConvo ??
({
conversationId,
title,
} as TConversation),
true,
true,
);
};
if (!conversationId) {
return null;
}
const clickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
const conversation = findConversationInInfinite(searchQueryRes?.data, conversationId);
if (!conversation) {
return;
}
document.title = message.title ?? '';
navigateWithLastTools(conversation, true, true);
};
return (
<div className="visible mt-0 flex items-center justify-center gap-1 self-end text-text-secondary lg:justify-start">
<button
type="button"
className="ml-0 flex cursor-pointer items-center gap-1.5 rounded-md p-1 text-xs hover:text-text-primary hover:underline"
onClick={clickHandler}
title={localize('com_ui_go_to_conversation')}