import { useState } from "react"; import { useSearchParams } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { api, type BrowseResult, type MediaItem } from "../../api/client"; import MediaViewer from "../MediaViewer/MediaViewer"; import DoomScrollViewer from "../DoomScrollViewer/DoomScrollViewer"; interface Props { libraryId: number; } export default function FileBrowser({ libraryId }: Props) { const [searchParams] = useSearchParams(); const [libraryPaths, setLibraryPaths] = useState>({ [libraryId]: searchParams.get("path") ?? "", }); const [viewingId, setViewingId] = useState(null); const [doomScrollItems, setDoomScrollItems] = useState(null); const currentPath = libraryPaths[libraryId] ?? ""; const { data, isLoading } = useQuery({ queryKey: ["browse", libraryId, currentPath], queryFn: () => api.libraries.browse(libraryId, currentPath), }); const pathParts = currentPath ? currentPath.split("/").filter(Boolean) : []; function navigate(relPath: string) { setLibraryPaths((prev) => ({ ...prev, [libraryId]: relPath })); setViewingId(null); } async function startDoomScroll() { const items = await api.libraries.doomScroll(libraryId, currentPath); setDoomScrollItems([...items].sort(() => Math.random() - 0.5)); } function handleViewInLibrary(item: MediaItem) { const dirPath = item.rel_path.split("/").slice(0, -1).join("/"); navigate(dirPath); setDoomScrollItems(null); } return (
{/* Breadcrumb */} {isLoading &&

Loading…

} {/* Grid */}
{data?.entries.map((entry) => (
{ if (entry.type === "dir") navigate(entry.rel_path); else if (entry.media_item_id) setViewingId(entry.media_item_id); }} style={{ cursor: entry.type === "dir" || entry.media_item_id ? "pointer" : "default", border: "1px solid var(--border)", borderRadius: 6, overflow: "hidden", background: "var(--bg-card)", display: "flex", flexDirection: "column", alignItems: "center", opacity: entry.type !== "dir" && !entry.media_item_id ? 0.5 : 1, }} > {entry.type === "dir" ? (
📁
) : ( {entry.name} { (e.target as HTMLImageElement).style.display = "none"; }} /> )}
{entry.name}
))}
{viewingId && data && ( setViewingId(null)} onNavigate={setViewingId} /> )} {doomScrollItems && ( setDoomScrollItems(null)} onViewInLibrary={handleViewInLibrary} /> )}
); }