Sidebar: scope count badges to current user's library
PhotoPrism's /api/v1/config.count is library-wide and the same value for every authenticated session. That made non-admins (and admins with a non-empty BasePath) see badges that didn't match what the timeline actually showed them. Replaces the direct `configQuery.data?.count?.<bucket>` reads in LeftSidebar with per-bucket queries against PhotoPrism's /photos endpoint. The new `countPhotos(q)` helper sets `count=10000` and reads the X-Count response header to get the true total in one round -trip (PhotoPrism's ACL filter is what scopes the result, so the header reflects "what this session can see"). Each bucket query appends `path:"<BasePath>*"` so admins-with-a- BasePath stay scoped too; non-admins without a BasePath short-circuit to `uid:none` (their effective visibility is zero, no point querying). Admins without a BasePath skip the scoped queries entirely and keep using the precomputed /config totals — same network footprint as before for the common case. Affected badges: Favorites, Hidden, Archive, Review, Tags (labels component). Map already used `geoQuery` whose result is ACL-filtered server-side, so its badge is per-user-correct without changes. The `favorites` field was missing from PpClientConfig.count's TypeScript type; added it. Resolves the `test`-user complaint: sidebar showed the admin library's totals next to Review / Hidden / Archive / Favorites because those numbers came from /config, not from a user-scoped query.
This commit is contained in:
@@ -155,6 +155,28 @@ export async function listPhotos(params: ListPhotosParams = {}): Promise<PpPhoto
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count photos matching a DSL query, scoped to whatever the caller's
|
||||
* session ACL allows. PhotoPrism doesn't expose a dedicated "count
|
||||
* only" endpoint, but the `X-Count` header on `/photos` returns the
|
||||
* page size — which equals the total when `count` is set above the
|
||||
* library size. 10000 is generously above the realistic per-user
|
||||
* library and well under PhotoPrism's server-side ceiling, so a single
|
||||
* round-trip yields the true total without paginating.
|
||||
*
|
||||
* Used by the LeftSidebar to render bucket badges that reflect what
|
||||
* the signed-in user actually sees, not the global library aggregate
|
||||
* exposed by `/config.count`.
|
||||
*/
|
||||
export async function countPhotos(q: string): Promise<number> {
|
||||
const resp = await http.get('/photos', {
|
||||
params: { count: 10000, offset: 0, merged: false, q }
|
||||
});
|
||||
const header = resp.headers['x-count'];
|
||||
const n = typeof header === 'string' ? parseInt(header, 10) : NaN;
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
}
|
||||
|
||||
export async function getPhoto(uid: string): Promise<PpPhoto> {
|
||||
const { data } = await http.get<PpPhoto>(`/photos/${uid}`);
|
||||
return data;
|
||||
|
||||
Reference in New Issue
Block a user