import { useState, type FC, useCallback } from 'react'; import { useRecoilValue } from 'recoil'; import { Constants } from 'librechat-data-provider'; import { Menu, MenuButton, MenuItems } from '@headlessui/react'; import { BookmarkFilledIcon, BookmarkIcon } from '@radix-ui/react-icons'; import { useConversationTagsQuery, useTagConversationMutation } from '~/data-provider'; import { BookmarkMenuItems } from './Bookmarks/BookmarkMenuItems'; import { BookmarkContext } from '~/Providers/BookmarkContext'; import { BookmarkEditDialog } from '~/components/Bookmarks'; import { NotificationSeverity } from '~/common'; import { useToastContext } from '~/Providers'; import { useBookmarkSuccess } from '~/hooks'; import { Spinner } from '~/components'; import { cn } from '~/utils'; import store from '~/store'; const BookmarkMenu: FC = () => { const { showToast } = useToastContext(); const conversation = useRecoilValue(store.conversationByIndex(0)) || undefined; const conversationId = conversation?.conversationId ?? ''; const onSuccess = useBookmarkSuccess(conversationId); const [tags, setTags] = useState(conversation?.tags || []); const [open, setOpen] = useState(false); const { mutateAsync, isLoading } = useTagConversationMutation(conversationId); const { data } = useConversationTagsQuery(); const isActiveConvo = Boolean( conversation && conversationId && conversationId !== Constants.NEW_CONVO && conversationId !== 'search', ); const handleSubmit = useCallback( async (tag?: string): Promise => { if (tag === undefined || tag === '' || !conversationId) { showToast({ message: 'Invalid tag or conversationId', severity: NotificationSeverity.ERROR, }); return; } const newTags = tags.includes(tag) ? tags.filter((t) => t !== tag) : [...tags, tag]; await mutateAsync( { tags: newTags, }, { onSuccess: (newTags: string[]) => { setTags(newTags); onSuccess(newTags); }, onError: () => { showToast({ message: 'Error adding bookmark', severity: NotificationSeverity.ERROR, }); }, }, ); }, [tags, conversationId, mutateAsync, setTags, onSuccess, showToast], ); if (!isActiveConvo) { return <>; } const renderButtonContent = () => { if (isLoading) { return ; } if (tags.length > 0) { return ; } return ; }; const handleToggleOpen = () => { setOpen(!open); return Promise.resolve(); }; return ( <> {({ open }) => ( <> {renderButtonContent()} )} ); }; export default BookmarkMenu;