2024-08-08 21:25:10 -04:00
|
|
|
import { useState, type FC } from 'react';
|
2024-07-29 07:45:59 -07:00
|
|
|
import { useRecoilValue } from 'recoil';
|
2024-08-08 21:25:10 -04:00
|
|
|
import { Constants } from 'librechat-data-provider';
|
2024-07-29 07:45:59 -07:00
|
|
|
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
|
|
|
|
import { BookmarkFilledIcon, BookmarkIcon } from '@radix-ui/react-icons';
|
|
|
|
|
import { useConversationTagsQuery, useTagConversationMutation } from '~/data-provider';
|
|
|
|
|
import { BookmarkMenuItems } from './Bookmarks/BookmarkMenuItems';
|
|
|
|
|
import { BookmarkContext } from '~/Providers/BookmarkContext';
|
2024-08-08 21:25:10 -04:00
|
|
|
import { useLocalize, useBookmarkSuccess } from '~/hooks';
|
2024-07-29 07:45:59 -07:00
|
|
|
import { Spinner } from '~/components';
|
|
|
|
|
import { cn } from '~/utils';
|
|
|
|
|
import store from '~/store';
|
|
|
|
|
|
|
|
|
|
const BookmarkMenu: FC = () => {
|
|
|
|
|
const localize = useLocalize();
|
|
|
|
|
|
2024-08-08 21:25:10 -04:00
|
|
|
const conversation = useRecoilValue(store.conversationByIndex(0));
|
|
|
|
|
const conversationId = conversation?.conversationId ?? '';
|
|
|
|
|
const onSuccess = useBookmarkSuccess(conversationId);
|
|
|
|
|
const [tags, setTags] = useState<string[]>(conversation?.tags || []);
|
2024-07-29 07:45:59 -07:00
|
|
|
|
|
|
|
|
const [open, setIsOpen] = useState(false);
|
|
|
|
|
|
2024-08-08 21:25:10 -04:00
|
|
|
const { mutateAsync, isLoading } = useTagConversationMutation(conversationId);
|
2024-07-29 07:45:59 -07:00
|
|
|
|
|
|
|
|
const { data } = useConversationTagsQuery();
|
|
|
|
|
|
|
|
|
|
const isActiveConvo =
|
2024-08-08 21:25:10 -04:00
|
|
|
conversation &&
|
|
|
|
|
conversationId &&
|
|
|
|
|
conversationId !== Constants.NEW_CONVO &&
|
|
|
|
|
conversationId !== 'search';
|
2024-07-29 07:45:59 -07:00
|
|
|
|
|
|
|
|
if (!isActiveConvo) {
|
|
|
|
|
return <></>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onOpenChange = async (open: boolean) => {
|
|
|
|
|
if (!open) {
|
|
|
|
|
setIsOpen(open);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (open && tags && tags.length > 0) {
|
|
|
|
|
setIsOpen(open);
|
|
|
|
|
} else {
|
2024-08-08 21:25:10 -04:00
|
|
|
if (conversation && conversationId) {
|
|
|
|
|
await mutateAsync(
|
|
|
|
|
{
|
2024-08-09 02:11:56 -04:00
|
|
|
tags: [Constants.SAVED_TAG as 'Saved'],
|
2024-08-08 21:25:10 -04:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
onSuccess: (newTags: string[]) => {
|
|
|
|
|
setTags(newTags);
|
|
|
|
|
onSuccess(newTags);
|
|
|
|
|
},
|
|
|
|
|
onError: () => {
|
|
|
|
|
console.error('Error adding bookmark');
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
2024-07-29 07:45:59 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-08 21:25:10 -04:00
|
|
|
const renderButtonContent = () => {
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
return <Spinner />;
|
|
|
|
|
}
|
|
|
|
|
if (tags && tags.length > 0) {
|
|
|
|
|
return <BookmarkFilledIcon className="icon-sm" />;
|
|
|
|
|
}
|
|
|
|
|
return <BookmarkIcon className="icon-sm" />;
|
|
|
|
|
};
|
|
|
|
|
|
2024-07-29 07:45:59 -07:00
|
|
|
return (
|
|
|
|
|
<Root open={open} onOpenChange={onOpenChange}>
|
|
|
|
|
<Trigger asChild>
|
|
|
|
|
<button
|
2024-08-08 21:25:10 -04:00
|
|
|
id="header-bookmarks-menu"
|
2024-07-29 07:45:59 -07:00
|
|
|
className={cn(
|
2024-08-08 21:25:10 -04:00
|
|
|
'pointer-cursor relative flex flex-col rounded-md border border-border-light bg-transparent text-left focus:outline-none focus:ring-0 sm:text-sm',
|
|
|
|
|
'hover:bg-header-button-hover radix-state-open:bg-header-button-hover',
|
|
|
|
|
'z-50 flex h-[40px] min-w-4 flex-none items-center justify-center px-3 focus:outline-offset-2 focus:ring-0 focus-visible:ring-2 focus-visible:ring-ring-primary ',
|
2024-07-29 07:45:59 -07:00
|
|
|
)}
|
|
|
|
|
title={localize('com_ui_bookmarks')}
|
|
|
|
|
>
|
2024-08-08 21:25:10 -04:00
|
|
|
{renderButtonContent()}
|
2024-07-29 07:45:59 -07:00
|
|
|
</button>
|
|
|
|
|
</Trigger>
|
|
|
|
|
<Portal>
|
|
|
|
|
<Content
|
2024-08-08 21:25:10 -04:00
|
|
|
className="mt-2 grid max-h-[500px] w-full min-w-[240px] overflow-y-auto rounded-lg border border-border-medium bg-header-primary text-text-primary shadow-lg"
|
2024-07-29 07:45:59 -07:00
|
|
|
side="bottom"
|
|
|
|
|
align="start"
|
|
|
|
|
>
|
|
|
|
|
{data && conversation && (
|
|
|
|
|
<BookmarkContext.Provider value={{ bookmarks: data }}>
|
2024-08-08 21:25:10 -04:00
|
|
|
<BookmarkMenuItems conversation={conversation} tags={tags ?? []} setTags={setTags} />
|
2024-07-29 07:45:59 -07:00
|
|
|
</BookmarkContext.Provider>
|
|
|
|
|
)}
|
|
|
|
|
</Content>
|
|
|
|
|
</Portal>
|
|
|
|
|
</Root>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default BookmarkMenu;
|