'use client'; import clsx from 'clsx'; import { motion } from 'framer-motion'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { toast } from 'react-toastify'; import { IconFolder, IconFolderClosed, IconFolderEmpty, IconFolderOpened, IconFolderTree } from '@/components/Icons'; import BadgeHelp from '@/components/info/BadgeHelp'; import { CProps } from '@/components/props'; import MiniButton from '@/components/ui/MiniButton'; import { FolderNode, FolderTree } from '@/models/FolderTree'; import { HelpTopic } from '@/models/miscellaneous'; import { animateSideView } from '@/styling/animations'; import { PARAMETER, prefixes } from '@/utils/constants'; import { information, labelFolderNode } from '@/utils/labels'; interface LibraryTableProps { folders: FolderTree; currentFolder: string; setFolder: React.Dispatch>; toggleFolderMode: () => void; } function LibraryFolders({ folders, currentFolder, setFolder, toggleFolderMode }: LibraryTableProps) { const activeNode = useMemo(() => folders.at(currentFolder), [folders, currentFolder]); const items = useMemo(() => folders.getTree(), [folders]); const [folded, setFolded] = useState(items); useLayoutEffect(() => { setFolded(items.filter(item => item !== activeNode && (!activeNode || !activeNode.hasPredecessor(item)))); }, [items, activeNode]); const onFoldItem = useCallback( (target: FolderNode, showChildren: boolean) => { setFolded(prev => items.filter(item => { if (item === target) { return !showChildren; } if (!showChildren && item.hasPredecessor(target)) { return true; } else { return prev.includes(item); } }) ); }, [items] ); const handleClickFolder = useCallback( (event: CProps.EventMouse, target: FolderNode) => { event.preventDefault(); event.stopPropagation(); if (event.ctrlKey || event.metaKey) { navigator.clipboard .writeText(target.getPath()) .then(() => toast.success(information.pathReady)) .catch(console.error); } else { setFolder(target.getPath()); } }, [setFolder] ); const handleClickFold = useCallback( (event: CProps.EventMouse, target: FolderNode, showChildren: boolean) => { event.preventDefault(); event.stopPropagation(); onFoldItem(target, showChildren); }, [onFoldItem] ); return (
} title='Переключение в режим Поиск' onClick={toggleFolderMode} />
{items.map((item, index) => !item.parent || !folded.includes(item.parent) ? (
5 ? 5 : item.rank) * 0.5 + 0.5}rem` }} onClick={event => handleClickFolder(event, item)} > {item.children.size > 0 ? ( ) : ( ) ) : ( ) } onClick={event => handleClickFold(event, item, folded.includes(item))} /> ) : (
{item.filesInside ? ( ) : ( )}
)}
{labelFolderNode(item)}
) : null )}
); } export default LibraryFolders;