2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2024-06-19 22:10:15 +03:00
|
|
|
import { AnimatePresence } from 'framer-motion';
|
2024-04-30 16:06:25 +03:00
|
|
|
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
2023-11-26 02:24:16 +03:00
|
|
|
|
2024-03-20 15:27:32 +03:00
|
|
|
import DataLoader from '@/components/wrap/DataLoader';
|
2024-06-14 21:43:37 +03:00
|
|
|
import { useAuth } from '@/context/AuthContext';
|
2023-12-13 14:32:57 +03:00
|
|
|
import { useLibrary } from '@/context/LibraryContext';
|
|
|
|
import useLocalStorage from '@/hooks/useLocalStorage';
|
2024-06-02 23:41:46 +03:00
|
|
|
import { ILibraryItem, LocationHead } from '@/models/library';
|
|
|
|
import { ILibraryFilter } from '@/models/miscellaneous';
|
2024-03-27 15:32:59 +03:00
|
|
|
import { storage } from '@/utils/constants';
|
2024-06-02 23:41:46 +03:00
|
|
|
import { toggleTristateFlag } from '@/utils/utils';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2024-06-26 19:47:31 +03:00
|
|
|
import TableLibraryItems from './TableLibraryItems';
|
|
|
|
import ToolbarSearch from './ToolbarSearch';
|
|
|
|
import ViewSideFolders from './ViewSideFolders';
|
2023-11-26 02:24:16 +03:00
|
|
|
|
|
|
|
function LibraryPage() {
|
|
|
|
const library = useLibrary();
|
2024-06-14 21:43:37 +03:00
|
|
|
const { user } = useAuth();
|
2023-12-05 01:22:44 +03:00
|
|
|
const [items, setItems] = useState<ILibraryItem[]>([]);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
|
|
|
const [query, setQuery] = useState('');
|
2024-06-02 23:41:46 +03:00
|
|
|
const [path, setPath] = useState('');
|
|
|
|
|
|
|
|
const [head, setHead] = useLocalStorage<LocationHead | undefined>(storage.librarySearchHead, undefined);
|
2024-06-19 22:10:15 +03:00
|
|
|
const [folderMode, setFolderMode] = useLocalStorage<boolean>(storage.librarySearchFolderMode, true);
|
|
|
|
const [folder, setFolder] = useLocalStorage<string>(storage.librarySearchFolder, '');
|
2024-06-02 23:41:46 +03:00
|
|
|
const [isVisible, setIsVisible] = useLocalStorage<boolean | undefined>(storage.librarySearchVisible, true);
|
|
|
|
const [isSubscribed, setIsSubscribed] = useLocalStorage<boolean | undefined>(
|
|
|
|
storage.librarySearchSubscribed,
|
|
|
|
undefined
|
2023-12-28 14:04:44 +03:00
|
|
|
);
|
2024-06-02 23:41:46 +03:00
|
|
|
const [isOwned, setIsOwned] = useLocalStorage<boolean | undefined>(storage.librarySearchEditor, undefined);
|
|
|
|
const [isEditor, setIsEditor] = useLocalStorage<boolean | undefined>(storage.librarySearchEditor, undefined);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
2024-06-02 23:41:46 +03:00
|
|
|
const filter: ILibraryFilter = useMemo(
|
|
|
|
() => ({
|
|
|
|
head: head,
|
|
|
|
path: path,
|
|
|
|
query: query,
|
2024-06-14 21:43:37 +03:00
|
|
|
isEditor: user ? isEditor : undefined,
|
|
|
|
isOwned: user ? isOwned : undefined,
|
|
|
|
isSubscribed: user ? isSubscribed : undefined,
|
2024-06-19 22:10:15 +03:00
|
|
|
isVisible: user ? isVisible : true,
|
|
|
|
folderMode: folderMode,
|
|
|
|
folder: folder
|
2024-06-02 23:41:46 +03:00
|
|
|
}),
|
2024-06-19 22:10:15 +03:00
|
|
|
[head, path, query, isEditor, isOwned, isSubscribed, isVisible, user, folderMode, folder]
|
2024-06-02 23:41:46 +03:00
|
|
|
);
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2024-06-18 15:07:41 +03:00
|
|
|
const hasCustomFilter = useMemo(
|
|
|
|
() =>
|
|
|
|
!!filter.path ||
|
|
|
|
!!filter.query ||
|
|
|
|
filter.head !== undefined ||
|
|
|
|
filter.isEditor !== undefined ||
|
|
|
|
filter.isOwned !== undefined ||
|
|
|
|
filter.isSubscribed !== undefined ||
|
2024-06-19 22:10:15 +03:00
|
|
|
filter.isVisible !== true ||
|
|
|
|
!!filter.folder,
|
2024-06-18 15:07:41 +03:00
|
|
|
[filter]
|
|
|
|
);
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
useLayoutEffect(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
setItems(library.applyFilter(filter));
|
|
|
|
}, [library, filter, filter.query]);
|
|
|
|
|
2024-06-02 23:41:46 +03:00
|
|
|
const toggleVisible = useCallback(() => setIsVisible(prev => toggleTristateFlag(prev)), [setIsVisible]);
|
|
|
|
const toggleOwned = useCallback(() => setIsOwned(prev => toggleTristateFlag(prev)), [setIsOwned]);
|
|
|
|
const toggleSubscribed = useCallback(() => setIsSubscribed(prev => toggleTristateFlag(prev)), [setIsSubscribed]);
|
|
|
|
const toggleEditor = useCallback(() => setIsEditor(prev => toggleTristateFlag(prev)), [setIsEditor]);
|
2024-06-19 22:10:15 +03:00
|
|
|
const toggleFolderMode = useCallback(() => setFolderMode(prev => !prev), [setFolderMode]);
|
2024-06-02 23:41:46 +03:00
|
|
|
|
|
|
|
const resetFilter = useCallback(() => {
|
2023-11-26 02:24:16 +03:00
|
|
|
setQuery('');
|
2024-06-02 23:41:46 +03:00
|
|
|
setPath('');
|
|
|
|
setHead(undefined);
|
|
|
|
setIsVisible(true);
|
|
|
|
setIsSubscribed(undefined);
|
|
|
|
setIsOwned(undefined);
|
|
|
|
setIsEditor(undefined);
|
2024-06-19 22:10:15 +03:00
|
|
|
setFolder('');
|
|
|
|
}, [setHead, setIsVisible, setIsSubscribed, setIsOwned, setIsEditor, setFolder]);
|
2023-11-26 02:24:16 +03:00
|
|
|
|
2024-04-30 16:06:25 +03:00
|
|
|
const view = useMemo(
|
|
|
|
() => (
|
2024-06-26 19:47:31 +03:00
|
|
|
<TableLibraryItems
|
2024-06-02 23:41:46 +03:00
|
|
|
resetQuery={resetFilter} // prettier: split lines
|
2024-04-30 16:06:25 +03:00
|
|
|
items={items}
|
2024-06-19 22:10:15 +03:00
|
|
|
folderMode={folderMode}
|
|
|
|
toggleFolderMode={toggleFolderMode}
|
2024-04-30 16:06:25 +03:00
|
|
|
/>
|
|
|
|
),
|
2024-06-19 22:10:15 +03:00
|
|
|
[resetFilter, items, folderMode, toggleFolderMode]
|
2024-04-30 16:06:25 +03:00
|
|
|
);
|
|
|
|
|
2023-11-26 02:24:16 +03:00
|
|
|
return (
|
2024-01-07 03:29:16 +03:00
|
|
|
<DataLoader
|
2024-06-02 23:41:46 +03:00
|
|
|
id='library-page' // prettier: split lines
|
2024-01-07 03:29:16 +03:00
|
|
|
isLoading={library.loading}
|
2024-06-19 22:10:15 +03:00
|
|
|
error={library.loadingError}
|
2024-01-07 03:29:16 +03:00
|
|
|
hasNoData={library.items.length === 0}
|
|
|
|
>
|
2024-06-26 19:47:31 +03:00
|
|
|
<ToolbarSearch
|
2024-06-18 15:07:41 +03:00
|
|
|
total={library.items.length ?? 0}
|
|
|
|
filtered={items.length}
|
|
|
|
hasCustomFilter={hasCustomFilter}
|
2024-01-07 03:29:16 +03:00
|
|
|
query={query}
|
|
|
|
setQuery={setQuery}
|
2024-06-02 23:41:46 +03:00
|
|
|
path={path}
|
|
|
|
setPath={setPath}
|
|
|
|
head={head}
|
|
|
|
setHead={setHead}
|
|
|
|
isVisible={isVisible}
|
|
|
|
isOwned={isOwned}
|
|
|
|
toggleOwned={toggleOwned}
|
|
|
|
toggleVisible={toggleVisible}
|
|
|
|
isSubscribed={isSubscribed}
|
|
|
|
toggleSubscribed={toggleSubscribed}
|
|
|
|
isEditor={isEditor}
|
|
|
|
toggleEditor={toggleEditor}
|
2024-06-18 15:07:41 +03:00
|
|
|
resetFilter={resetFilter}
|
2024-06-19 22:10:15 +03:00
|
|
|
folderMode={folderMode}
|
|
|
|
toggleFolderMode={toggleFolderMode}
|
2024-01-07 03:29:16 +03:00
|
|
|
/>
|
2024-06-19 22:10:15 +03:00
|
|
|
|
|
|
|
<div className='flex'>
|
2024-06-19 22:32:15 +03:00
|
|
|
<AnimatePresence initial={false}>
|
2024-06-19 22:10:15 +03:00
|
|
|
{folderMode ? (
|
2024-06-26 19:47:31 +03:00
|
|
|
<ViewSideFolders
|
2024-06-19 22:10:15 +03:00
|
|
|
currentFolder={folder} // prettier: split-lines
|
|
|
|
setFolder={setFolder}
|
|
|
|
folders={library.folders}
|
|
|
|
toggleFolderMode={toggleFolderMode}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
</AnimatePresence>
|
|
|
|
{view}
|
|
|
|
</div>
|
2024-01-07 03:29:16 +03:00
|
|
|
</DataLoader>
|
2023-12-28 14:04:44 +03:00
|
|
|
);
|
2023-11-26 02:24:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
export default LibraryPage;
|