fix library tag search: dynamic tagGroups, clear tags, cache-bust
Three bugs in library.tsx (all previously fixed, lost in UX rewrite):
1. tagGroups now recomputed from items passing current collection +
search filters — only shows tags that will produce results
2. Collection switching clears selectedTags (prevents stale empty)
3. Cache-buster on fetch("/library.json?v=" + Date.now())
fix #71
This commit is contained in:
@@ -76,7 +76,7 @@ export default function Library(): JSX.Element {
|
|||||||
const searchRef = useRef<HTMLInputElement>(null);
|
const searchRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("/library.json")
|
fetch("/library.json?v=" + Date.now())
|
||||||
.then((r) => r.json())
|
.then((r) => r.json())
|
||||||
.then((d: LibraryData) => setData(d))
|
.then((d: LibraryData) => setData(d))
|
||||||
.catch(() => setData({ items: [], collections: [], tags: [] }));
|
.catch(() => setData({ items: [], collections: [], tags: [] }));
|
||||||
@@ -106,11 +106,6 @@ export default function Library(): JSX.Element {
|
|||||||
return () => document.removeEventListener("keydown", handler);
|
return () => document.removeEventListener("keydown", handler);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const tagGroups = useMemo(
|
|
||||||
() => (data ? groupTags(data.tags) : {}),
|
|
||||||
[data],
|
|
||||||
);
|
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
let items = data.items;
|
let items = data.items;
|
||||||
@@ -139,6 +134,38 @@ export default function Library(): JSX.Element {
|
|||||||
return items;
|
return items;
|
||||||
}, [data, debouncedSearch, selectedCollection, selectedTags]);
|
}, [data, debouncedSearch, selectedCollection, selectedTags]);
|
||||||
|
|
||||||
|
// Recompute visible tags from items that pass collection + search filters
|
||||||
|
// so clicking a tag is guaranteed to produce results.
|
||||||
|
const tagGroups = useMemo(() => {
|
||||||
|
if (!data) return {};
|
||||||
|
let pool = data.items;
|
||||||
|
if (selectedCollection) {
|
||||||
|
pool = pool.filter((i) => i.collections.includes(selectedCollection));
|
||||||
|
}
|
||||||
|
if (debouncedSearch.trim()) {
|
||||||
|
const q = debouncedSearch.toLowerCase();
|
||||||
|
pool = pool.filter(
|
||||||
|
(i) =>
|
||||||
|
i.title.toLowerCase().includes(q) ||
|
||||||
|
i.abstract.toLowerCase().includes(q) ||
|
||||||
|
i.tags.some((t) => t.toLowerCase().includes(q)) ||
|
||||||
|
i.creators.some((c) => c.toLowerCase().includes(q)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const counts: Record<string, number> = {};
|
||||||
|
for (const item of pool) {
|
||||||
|
for (const t of item.tags) {
|
||||||
|
counts[t] = (counts[t] || 0) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const liveTags: Tag[] = Object.entries(counts).map(([name, count]) => ({
|
||||||
|
name,
|
||||||
|
count,
|
||||||
|
}));
|
||||||
|
liveTags.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
return groupTags(liveTags);
|
||||||
|
}, [data, selectedCollection, debouncedSearch]);
|
||||||
|
|
||||||
const pageItems = useMemo(
|
const pageItems = useMemo(
|
||||||
() => filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE),
|
() => filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE),
|
||||||
[filtered, page],
|
[filtered, page],
|
||||||
@@ -182,6 +209,7 @@ export default function Library(): JSX.Element {
|
|||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCollection("");
|
setSelectedCollection("");
|
||||||
|
setSelectedTags(new Set());
|
||||||
setPage(0);
|
setPage(0);
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -202,6 +230,7 @@ export default function Library(): JSX.Element {
|
|||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCollection(c.key);
|
setSelectedCollection(c.key);
|
||||||
|
setSelectedTags(new Set());
|
||||||
setPage(0);
|
setPage(0);
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in New Issue
Block a user