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 { useSWRMUTxCurrentUserBookmarks } from '~/stores/bookmark'; import { useSWRxBookmarkFolderAndChild } from '~/stores/bookmark-folder'; import { useCurrentUser } from '~/stores/context'; import { useSWRMUTxPageInfo } from '~/stores/page'; import { BookmarkFolderMenuItem } from './BookmarkFolderMenuItem'; type BookmarkFolderMenuProps = { isOpen: boolean, pageId: string, isBookmarked: boolean, onToggle?: () => void, onUnbookmark?: () => void, children?: React.ReactNode, } export const BookmarkFolderMenu = (props: BookmarkFolderMenuProps): JSX.Element => { const { isOpen, pageId, isBookmarked, onToggle, onUnbookmark, children, } = props; const { t } = useTranslation(); const [selectedItem, setSelectedItem] = useState(null); const { data: currentUser } = useCurrentUser(); const { data: bookmarkFolders, mutate: mutateBookmarkFolders } = useSWRxBookmarkFolderAndChild(currentUser?._id); const { trigger: mutateCurrentUserBookmarks } = useSWRMUTxCurrentUserBookmarks(); const { trigger: mutatePageInfo } = useSWRMUTxPageInfo(pageId); const isBookmarkFolderExists = useMemo((): boolean => { return bookmarkFolders != null && bookmarkFolders.length > 0; }, [bookmarkFolders]); const toggleBookmarkHandler = useCallback(async() => { try { await toggleBookmark(pageId, isBookmarked); } catch (err) { toastError(err); } }, [isBookmarked, pageId]); const onUnbookmarkHandler = useCallback(async() => { if (onUnbookmark != null) { onUnbookmark(); } await toggleBookmarkHandler(); setSelectedItem(null); mutateCurrentUserBookmarks(); mutateBookmarkFolders(); mutatePageInfo(); }, [onUnbookmark, toggleBookmarkHandler, mutateCurrentUserBookmarks, mutateBookmarkFolders, mutatePageInfo]); const toggleHandler = useCallback(async() => { // on close if (isOpen && bookmarkFolders != null) { bookmarkFolders.forEach((bookmarkFolder) => { bookmarkFolder.bookmarks.forEach((bookmark) => { if (bookmark.page._id === pageId) { setSelectedItem(bookmarkFolder._id); } }); }); } if (onToggle != null) { onToggle(); } if (selectedItem == null) { setSelectedItem('root'); } if (!isOpen && !isBookmarked) { try { await toggleBookmarkHandler(); mutateCurrentUserBookmarks(); mutatePageInfo(); } catch (err) { toastError(err); } } }, [isOpen, bookmarkFolders, onToggle, selectedItem, isBookmarked, pageId, toggleBookmarkHandler, mutateCurrentUserBookmarks, mutatePageInfo]); const onMenuItemClickHandler = useCallback(async(e, itemId: string) => { e.stopPropagation(); setSelectedItem(itemId); try { await addBookmarkToFolder(pageId, itemId === 'root' ? null : itemId); mutateCurrentUserBookmarks(); mutateBookmarkFolders(); mutatePageInfo(); } catch (err) { toastError(err); } }, [pageId, mutateCurrentUserBookmarks, mutateBookmarkFolders, mutatePageInfo]); 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() } ); };