Online browser + post detail: SPA talks to e621 directly
Backend:
- POST /api/files/lookup/ reports which MD5s are already in the library
Frontend:
- e621 client extended with post/tag/favorite types and helpers: post
search, post detail, batch posts by id, tag autocomplete, toggle
favorite
- /online: tag search with autocomplete, post grid with rating colors
and in-library badges, numbered pagination, page tag cloud, blacklist
panel and filtered counts from /users/me.json, anonymous hint
- /online/view/🆔 media viewer (sample or original, video support),
taxonomy-colored tags by category, specs sheet, favorite/unfavorite,
description, sources, pools and parent/children thumbnails
- Shared CollapsibleSidebar extracted from the library page; Online
added to the nav, command palette and sidebar toggle
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { X } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/cn";
|
||||
import { useUi } from "@/store/ui";
|
||||
|
||||
export function CollapsibleSidebar({
|
||||
title = "Filters",
|
||||
children,
|
||||
}: {
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const sidebarOpen = useUi((state) => state.sidebarOpen);
|
||||
const setSidebarOpen = useUi((state) => state.setSidebarOpen);
|
||||
|
||||
if (!sidebarOpen) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="fixed inset-0 z-40 bg-ctp-crust/60 backdrop-blur-sm lg:hidden"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<aside
|
||||
className={cn(
|
||||
"fixed inset-y-0 left-0 z-50 flex w-72 flex-col gap-5 overflow-y-auto border-r border-ctp-surface0 bg-ctp-base p-4",
|
||||
"lg:sticky lg:inset-y-auto lg:top-20 lg:z-auto lg:w-64 lg:shrink-0 lg:overflow-visible lg:rounded-lg lg:border",
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-semibold text-ctp-subtext1">{title}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
title="Close filters"
|
||||
className="rounded-md p-1 text-ctp-overlay0 transition hover:bg-ctp-surface0 hover:text-ctp-text lg:hidden"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
{children}
|
||||
</aside>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user