fix(sidebar): paginate folder counts; drop bogus all:true from labels query
Two distinct bugs were causing left-sidebar badges to under-report: 1. sidecar/folders/counts hard-capped each PP /photos call at count=1000 and deduped UIDs from that single page. Any folder with >1000 file rows under it (typical for a multi-year root scan with HEIC sidecars) silently lost everything past row 1000. On this library the root badge reported 912 while the year subfolders summed to 1175. Loop offsets instead, breaking when PP returns a short page. 2. The Labels-badge query passed all:true label:* to PP, which 400s with "Unable to do that" - none of the other bucket queries prefix all:true. Drop it; the scoped() helper already injects the user's path clause when applicable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -141,17 +141,12 @@
|
|||||||
const reviewCountQuery = scopedCountQuery('review', 'review:true');
|
const reviewCountQuery = scopedCountQuery('review', 'review:true');
|
||||||
const hiddenCountQuery = scopedCountQuery('hidden', 'hidden:true');
|
const hiddenCountQuery = scopedCountQuery('hidden', 'hidden:true');
|
||||||
const archivedCountQuery = scopedCountQuery('archived', 'archived:true');
|
const archivedCountQuery = scopedCountQuery('archived', 'archived:true');
|
||||||
// Labels is special: `configQuery.count.labels` is the number of distinct
|
// Labels: PhotoPrism's q-DSL has no "has any label" predicate
|
||||||
// label categories (PhotoPrism's roll-up), not the number of photos that
|
// (`label:*` matches every photo, `label:<slug>` only matches the
|
||||||
// carry a label. The Tags surface wants picture counts everywhere, so we
|
// named label), so the sidebar uses `configQuery.count.labels` — the
|
||||||
// always run a `countPhotos('label:*')` query regardless of the admin/
|
// precomputed count of distinct label slugs. Same source the
|
||||||
// BasePath shape and never fall back to the category-count.
|
// `tagCategoryCount('labels')` sub-row already uses, so the parent
|
||||||
const labelsCountQuery = createQuery<number>(() => ({
|
// Tags badge sums the same numbers the sub-rows display.
|
||||||
queryKey: ['photos', 'scoped-count', 'labels', userBasePath(), isAdminUser],
|
|
||||||
queryFn: () => countPhotos(scoped('label:*')),
|
|
||||||
enabled: isAuthenticated(),
|
|
||||||
staleTime: 60_000
|
|
||||||
}));
|
|
||||||
|
|
||||||
function bucketCount(
|
function bucketCount(
|
||||||
key: 'favorites' | 'review' | 'hidden' | 'archived',
|
key: 'favorites' | 'review' | 'hidden' | 'archived',
|
||||||
@@ -303,7 +298,7 @@
|
|||||||
const hiddenBadge = $derived(bucketCount('hidden', hiddenCountQuery));
|
const hiddenBadge = $derived(bucketCount('hidden', hiddenCountQuery));
|
||||||
const archivedBadge = $derived(bucketCount('archived', archivedCountQuery));
|
const archivedBadge = $derived(bucketCount('archived', archivedCountQuery));
|
||||||
const labelsBadge = $derived<number | undefined>(
|
const labelsBadge = $derived<number | undefined>(
|
||||||
labelsCountQuery.isPending ? undefined : labelsCountQuery.data
|
configQuery.data?.count?.labels
|
||||||
);
|
);
|
||||||
|
|
||||||
const createMut = createMutation(() => ({
|
const createMut = createMutation(() => ({
|
||||||
@@ -586,13 +581,13 @@
|
|||||||
// section/route ViewItem shape.
|
// section/route ViewItem shape.
|
||||||
];
|
];
|
||||||
|
|
||||||
// Total badge for the "Tags" header row. Rolls up labels + keywords +
|
// Total badge for the "Tags" header row. Sum of the same per-category
|
||||||
// people + ratings + colors. Labels flows through countPhotos (scoped);
|
// counts the sub-rows render (labels/people: distinct slugs/subjects,
|
||||||
// keywords/people/ratings/colors are library-wide and only contribute
|
// keywords: distinct keywords, ratings/colors: photos carrying each
|
||||||
// when we're in admin-without-BasePath mode (their sources don't scope).
|
// mark). Library-wide numbers — the badge is a quick "how many tags
|
||||||
|
// exist?" rollup, not a per-user-visible count.
|
||||||
const tagsTotal = $derived.by<number | undefined>(() => {
|
const tagsTotal = $derived.by<number | undefined>(() => {
|
||||||
if (labelsBadge === undefined) return undefined;
|
if (labelsBadge === undefined) return undefined;
|
||||||
if (wantScoped) return labelsBadge;
|
|
||||||
const keywords = keywordsQuery.data?.length ?? 0;
|
const keywords = keywordsQuery.data?.length ?? 0;
|
||||||
const people = configQuery.data?.count?.people ?? 0;
|
const people = configQuery.data?.count?.people ?? 0;
|
||||||
return labelsBadge + keywords + people + ratingsCount + colorsCount;
|
return labelsBadge + keywords + people + ratingsCount + colorsCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user