Initial commit

This commit is contained in:
admin
2026-05-26 22:46:00 +02:00
commit 7e2c2ff89c
256 changed files with 51523 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
"use client";
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
import { usePathname } from "next/navigation";
type Ctx = {
ids: Set<number>;
has: (id: number) => boolean;
toggle: (id: number) => void;
selectMany: (ids: number[]) => void;
clear: () => void;
visibleIds: number[];
setVisibleIds: (ids: number[]) => void;
};
const SelectCtx = createContext<Ctx | null>(null);
export function SelectionProvider({ children }: { children: React.ReactNode }) {
const [ids, setIds] = useState<Set<number>>(new Set());
const [visibleIds, setVisibleIdsState] = useState<number[]>([]);
// Guard against fresh-array identity churn: server-side renders pass a new
// `number[]` reference every time, which would otherwise re-fire all consumers.
const setVisibleIds = useCallback((next: number[]) => {
setVisibleIdsState((cur) => {
if (cur.length === next.length && cur.every((v, i) => v === next[i])) return cur;
return next;
});
}, []);
const toggle = useCallback((id: number) => setIds((cur) => {
const next = new Set(cur);
if (next.has(id)) next.delete(id); else next.add(id);
return next;
}), []);
const selectMany = useCallback((newIds: number[]) => setIds((cur) => {
const next = new Set(cur);
newIds.forEach((i) => next.add(i));
return next;
}), []);
const clear = useCallback(() => setIds(new Set()), []);
// Global route-change cleanup: pages without RegisterVisible (e.g.
// /actress, /category, /tag, /search) would otherwise carry stale
// selections across navigation. Clear on any pathname change.
const pathname = usePathname();
const lastPath = useRef<string | null>(null);
useEffect(() => {
if (lastPath.current !== null && lastPath.current !== pathname) {
setIds(new Set());
setVisibleIdsState([]);
}
lastPath.current = pathname;
}, [pathname]);
const value = useMemo<Ctx>(() => ({
ids,
has: (id) => ids.has(id),
toggle,
selectMany,
clear,
visibleIds,
setVisibleIds,
}), [ids, toggle, selectMany, clear, visibleIds, setVisibleIds]);
return <SelectCtx.Provider value={value}>{children}</SelectCtx.Provider>;
}
export function useSelection() {
const ctx = useContext(SelectCtx);
if (!ctx) throw new Error("useSelection must be used within SelectionProvider");
return ctx;
}