import clsx from 'clsx'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { FaSearch } from 'react-icons/fa'; import { PiPlus } from 'react-icons/pi'; import { PiSelectionAllDuotone } from 'react-icons/pi'; import { PiDotsThreeCircle } from 'react-icons/pi'; import { MdOutlineMenu, MdArrowBackIosNew } from 'react-icons/md'; import { IoMdCloseCircle } from 'react-icons/io'; import { useEnv } from '@/context/EnvContext'; import { useThemeStore } from '@/store/themeStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useResponsiveSize } from '@/hooks/useResponsiveSize'; import { useTrafficLightStore } from '@/store/trafficLightStore'; import { navigateToLibrary } from '@/utils/nav'; import { throttle } from '@/utils/throttle'; import useShortcuts from '@/hooks/useShortcuts'; import WindowButtons from '@/components/WindowButtons'; import Dropdown from '@/components/Dropdown'; import SettingsMenu from './SettingsMenu'; import ImportMenu from './ImportMenu'; import SortMenu from './SortMenu'; interface LibraryHeaderProps { isSelectMode: boolean; isSelectAll: boolean; onImportBooks: () => void; onToggleSelectMode: () => void; onSelectAll: () => void; onDeselectAll: () => void; } const LibraryHeader: React.FC = ({ isSelectMode, isSelectAll, onImportBooks, onToggleSelectMode, onSelectAll, onDeselectAll, }) => { const _ = useTranslation(); const router = useRouter(); const searchParams = useSearchParams(); const { appService } = useEnv(); const { statusBarHeight } = useThemeStore(); const { isTrafficLightVisible, initializeTrafficLightStore, initializeTrafficLightListeners, setTrafficLightVisibility, cleanupTrafficLightListeners, } = useTrafficLightStore(); const [searchQuery, setSearchQuery] = useState(searchParams?.get('q') ?? ''); const headerRef = useRef(null); const iconSize18 = useResponsiveSize(18); const iconSize20 = useResponsiveSize(20); useShortcuts({ onToggleSelectMode, }); // eslint-disable-next-line react-hooks/exhaustive-deps const throttledUpdateQueryParam = useCallback( throttle((value: string) => { const params = new URLSearchParams(searchParams?.toString()); if (value) { params.set('q', value); } else { params.delete('q'); } router.push(`?${params.toString()}`); }, 1000), [searchParams], ); const handleSearchChange = (e: React.ChangeEvent) => { const newQuery = e.target.value; setSearchQuery(newQuery); throttledUpdateQueryParam(newQuery); }; useEffect(() => { if (!appService?.hasTrafficLight) return; initializeTrafficLightStore(appService); initializeTrafficLightListeners(); setTrafficLightVisibility(true); return () => { cleanupTrafficLightListeners(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const windowButtonVisible = appService?.hasWindowBar && !isTrafficLightVisible; const isInGroupView = !!searchParams?.get('group'); return (
{isInGroupView && ( )}
{searchQuery && ( )}
} > {appService?.isMobile ? null : ( )}
{isSelectMode ? (
) : (
} > } > {appService?.hasWindowBar && ( )}
)}
); }; export default LibraryHeader;