import React, { useCallback, useMemo, useState } from 'react'; import { getCustomModifiers } from '@growi/ui/dist/utils'; import { useTranslation } from 'next-i18next'; import { DropdownItem, DropdownMenu, UncontrolledDropdown } from 'reactstrap'; import { addBookmarkToFolder, toggleBookmark } from '~/client/util/bookmark-utils'; import { toastError } from '~/client/util/toastr'; import { IBookmarkInfo } from '~/interfaces/bookmark-info'; import { useSWRBookmarkInfo, useSWRxUserBookmarks } from '~/stores/bookmark'; import { useSWRxBookmarkFolderAndChild } from '~/stores/bookmark-folder'; import { useCurrentUser } from '~/stores/context'; import { useSWRxPageInfo } from '~/stores/page'; import { BookmarkFolderMenuItem } from './BookmarkFolderMenuItem'; export const BookmarkFolderMenu: React.FC<{children?: React.ReactNode, bookmarkInfo: IBookmarkInfo }> = ({ children, bookmarkInfo }): JSX.Element => { const { t } = useTranslation(); const [selectedItem, setSelectedItem] = useState(null); const [isOpen, setIsOpen] = useState(false); const { data: currentUser } = useCurrentUser(); const { data: bookmarkFolders, mutate: mutateBookmarkFolders } = useSWRxBookmarkFolderAndChild(currentUser?._id); const { mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(bookmarkInfo.pageId); const { mutate: mutateUserBookmarks } = useSWRxUserBookmarks(currentUser?._id); const { mutate: mutatePageInfo } = useSWRxPageInfo(bookmarkInfo.pageId); const isBookmarked = bookmarkInfo.isBookmarked ?? false; const isBookmarkFolderExists = useMemo((): boolean => { return bookmarkFolders != null && bookmarkFolders.length > 0; }, [bookmarkFolders]); const toggleBookmarkHandler = useCallback(async() => { try { await toggleBookmark(bookmarkInfo.pageId, isBookmarked); } catch (err) { toastError(err); } }, [bookmarkInfo.pageId, isBookmarked]); const onUnbookmarkHandler = useCallback(async() => { await toggleBookmarkHandler(); setIsOpen(false); setSelectedItem(null); mutateUserBookmarks(); mutateBookmarkInfo(); mutateBookmarkFolders(); mutatePageInfo(); }, [mutateBookmarkFolders, mutateBookmarkInfo, mutatePageInfo, mutateUserBookmarks, toggleBookmarkHandler]); const toggleHandler = useCallback(async() => { setIsOpen(!isOpen); if (isOpen && bookmarkFolders != null) { bookmarkFolders.forEach((bookmarkFolder) => { bookmarkFolder.bookmarks.forEach((bookmark) => { if (bookmark.page._id === bookmarkInfo.pageId) { setSelectedItem(bookmarkFolder._id); } }); }); } if (selectedItem == null) { setSelectedItem('root'); } if (!isOpen && !isBookmarked) { try { await toggleBookmarkHandler(); mutateUserBookmarks(); mutateBookmarkInfo(); mutatePageInfo(); } catch (err) { toastError(err); } } }, [isOpen, bookmarkFolders, selectedItem, isBookmarked, bookmarkInfo.pageId, toggleBookmarkHandler, mutateUserBookmarks, mutateBookmarkInfo, mutatePageInfo]); const onMenuItemClickHandler = useCallback(async(e, itemId: string) => { e.stopPropagation(); setSelectedItem(itemId); try { await addBookmarkToFolder(bookmarkInfo.pageId, itemId === 'root' ? null : itemId); mutateUserBookmarks(); mutateBookmarkFolders(); mutateBookmarkInfo(); } catch (err) { toastError(err); } }, [bookmarkInfo.pageId, mutateUserBookmarks, mutateBookmarkFolders, mutateBookmarkInfo]); const renderBookmarkMenuItem = () => { return ( <> {' '} {t('bookmark_folder.cancel_bookmark')} {isBookmarkFolderExists && ( <>
onMenuItemClickHandler(e, 'root')} >
{bookmarkFolders?.map(folder => (
onMenuItemClickHandler(e, folder._id)} >
{folder.children?.map(child => (
onMenuItemClickHandler(e, child._id)} >
))}
))} )} ); }; return ( {children} { renderBookmarkMenuItem() } ); };