| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- import React, {
- useCallback, useState,
- } from 'react';
- import { useTranslation } from 'next-i18next';
- import {
- DropdownItem, DropdownMenu, UncontrolledDropdown,
- } from 'reactstrap';
- import { addBookmarkToFolder, addNewFolder, toggleBookmark } from '~/client/util/bookmark-utils';
- import { toastError } from '~/client/util/toastr';
- import { BookmarkFolderItems } from '~/interfaces/bookmark-info';
- import { useSWRBookmarkInfo, useSWRxCurrentUserBookmarks } from '~/stores/bookmark';
- import { useSWRxBookmarkFolderAndChild } from '~/stores/bookmark-folder';
- import { useSWRxCurrentPage } from '~/stores/page';
- import { FolderIcon } from '../Icons/FolderIcon';
- import { BookmarkFolderMenuItem } from './BookmarkFolderMenuItem';
- import { BookmarkFolderNameInput } from './BookmarkFolderNameInput';
- type Props = {
- children?: React.ReactNode
- }
- export const BookmarkFolderMenu = (props: Props): JSX.Element => {
- const { t } = useTranslation();
- const { children } = props;
- const [isCreateAction, setIsCreateAction] = useState(false);
- const { data: bookmarkFolders, mutate: mutateBookmarkFolderData } = useSWRxBookmarkFolderAndChild();
- const [selectedItem, setSelectedItem] = useState<string | null>(null);
- const { data: currentPage } = useSWRxCurrentPage();
- const { data: userBookmarkInfo, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(currentPage?._id);
- const { mutate: mutateUserBookmarks } = useSWRxCurrentUserBookmarks();
- const isBookmarked = userBookmarkInfo?.isBookmarked ?? false;
- const [isOpen, setIsOpen] = useState(false);
- const toggleBookmarkHandler = useCallback(async() => {
- try {
- if (currentPage != null) {
- await toggleBookmark(currentPage._id, isBookmarked);
- }
- }
- catch (err) {
- toastError(err);
- }
- }, [currentPage, isBookmarked]);
- const onClickNewBookmarkFolder = useCallback(() => {
- setIsCreateAction(true);
- }, []);
- const onUnbookmarkHandler = useCallback(async() => {
- await toggleBookmarkHandler();
- mutateUserBookmarks();
- mutateBookmarkInfo();
- mutateBookmarkFolderData();
- setSelectedItem(null);
- }, [mutateBookmarkFolderData, mutateBookmarkInfo, mutateUserBookmarks, toggleBookmarkHandler]);
- const toggleHandler = useCallback(async() => {
- setIsOpen(!isOpen);
- mutateBookmarkFolderData();
- if (isOpen && bookmarkFolders != null) {
- bookmarkFolders.forEach((bookmarkFolder) => {
- bookmarkFolder.bookmarks.forEach((bookmark) => {
- if (bookmark.page._id === currentPage?._id) {
- setSelectedItem(bookmarkFolder._id);
- }
- });
- });
- }
- if (!isOpen && !isBookmarked) {
- try {
- toggleBookmarkHandler();
- mutateUserBookmarks();
- mutateBookmarkInfo();
- setSelectedItem(null);
- }
- catch (err) {
- toastError(err);
- }
- }
- }, [isOpen, mutateBookmarkFolderData, bookmarkFolders, isBookmarked, currentPage?._id, toggleBookmarkHandler, mutateUserBookmarks, mutateBookmarkInfo]);
- const isBookmarkFolderExists = useCallback((): boolean => {
- return bookmarkFolders != null && bookmarkFolders.length > 0;
- }, [bookmarkFolders]);
- const onPressEnterHandlerForCreate = useCallback(async(folderName: string) => {
- try {
- await addNewFolder(folderName, null);
- await mutateBookmarkFolderData();
- setIsCreateAction(false);
- }
- catch (err) {
- toastError(err);
- }
- }, [mutateBookmarkFolderData]);
- const onMenuItemClickHandler = useCallback(async(itemId: string) => {
- try {
- if (isBookmarked) {
- await toggleBookmarkHandler();
- }
- if (currentPage != null) {
- await addBookmarkToFolder(currentPage._id, itemId);
- }
- mutateBookmarkInfo();
- mutateUserBookmarks();
- }
- catch (err) {
- toastError(err);
- }
- mutateBookmarkFolderData();
- setSelectedItem(itemId);
- }, [mutateBookmarkFolderData, isBookmarked, currentPage, mutateBookmarkInfo, mutateUserBookmarks, toggleBookmarkHandler]);
- const renderBookmarkMenuItem = (child?: BookmarkFolderItems[]) => {
- const renderSubmenu = () => {
- if (child == null) {
- return <></>;
- }
- return (
- <div className="bookmark-folder-submenu">
- {child.map(folder => (
- <div key={folder._id}>
- <div
- className="dropdown-item grw-bookmark-folder-menu-item"
- tabIndex={0}
- role="menuitem"
- onClick={() => onMenuItemClickHandler(folder._id)}
- >
- <BookmarkFolderMenuItem
- item={folder}
- isSelected={selectedItem === folder._id}
- onSelectedChild={() => setSelectedItem(null)}
- />
- {isOpen && renderSubmenu()}
- </div>
- </div>
- ))}
- </div>
- );
- };
- return (
- <>
- {isBookmarked && (
- <>
- <DropdownItem
- toggle={false}
- onClick={onUnbookmarkHandler}
- className={'grw-bookmark-folder-menu-item text-danger'}
- >
- <i className="fa fa-bookmark"></i>{' '}
- <span className="mx-2 ">
- {t('bookmark_folder.cancel_bookmark')}
- </span>
- </DropdownItem>
- <DropdownItem divider />
- </>
- )}
- {isCreateAction ? (
- <div className="mx-2">
- <BookmarkFolderNameInput
- onClickOutside={() => setIsCreateAction(false)}
- onPressEnter={onPressEnterHandlerForCreate}
- />
- </div>
- ) : (
- <DropdownItem
- toggle={false}
- onClick={onClickNewBookmarkFolder}
- className="grw-bookmark-folder-menu-item"
- >
- <FolderIcon isOpen={false} />
- <span className="mx-2 ">{t('bookmark_folder.new_folder')}</span>
- </DropdownItem>
- )}
- {isBookmarkFolderExists() && (
- <>
- <DropdownItem divider />
- {bookmarkFolders?.map(folder => (
- <div key={folder._id}>
- <div
- className="dropdown-item grw-bookmark-folder-menu-item"
- tabIndex={0}
- role="menuitem"
- onClick={() => onMenuItemClickHandler(folder._id)}
- >
- <BookmarkFolderMenuItem
- item={folder}
- isSelected={selectedItem === folder._id}
- onSelectedChild={() => setSelectedItem(null)}
- />
- {isOpen && renderSubmenu()}
- </div>
- </div>
- ))}
- </>
- )}
- </>
- );
- };
- return (
- <UncontrolledDropdown
- onToggle={toggleHandler}
- direction={ isBookmarkFolderExists() ? 'up' : 'down' }
- className='grw-bookmark-folder-dropdown'>
- {children}
- <DropdownMenu
- right
- className='grw-bookmark-folder-menu'
- positionFixed
- >
- { renderBookmarkMenuItem() }
- </DropdownMenu>
- </UncontrolledDropdown>
- );
- };
|