fix(notes): page PhotoPrism server-side so /notes shows every captioned photo
Client-side paging of listPhotosWithNotes stopped early for BasePath users: the sidecar post-filters each page by BasePath, so a full upstream page can arrive short, tripping the `length < PAGE` end condition before the library is exhausted — hiding notes past the first slice. Add GET /api/sidecar/notes: the sidecar pages /api/v1/photos to completion (keying the loop off the raw upstream page length), filters to non-empty Caption under the caller's BasePath, dedupes by UID, and returns the set. listPhotosWithNotes now calls this single endpoint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -639,25 +639,16 @@ export interface PhotoWithNote {
|
||||
}
|
||||
|
||||
export async function listPhotosWithNotes(): Promise<PhotoWithNote[]> {
|
||||
// PhotoPrism has no "caption is not empty" search filter, so we page the
|
||||
// whole library and keep the captioned rows. Paging (rather than a single
|
||||
// count:1000 fetch) means notes on photos older than the newest 1000 still
|
||||
// surface — the previous cap silently hid them.
|
||||
// The sidecar pages PhotoPrism to completion server-side and returns only
|
||||
// captioned, BasePath-scoped photos — paging client-side would stop early
|
||||
// because each page is BasePath-filtered before we see it (a full upstream
|
||||
// page can arrive short), silently hiding notes past the first slice.
|
||||
const { data } = await sidecar.get<PpPhoto[]>('/api/sidecar/notes');
|
||||
const out: PhotoWithNote[] = [];
|
||||
const seen = new Set<string>();
|
||||
const PAGE = 1000;
|
||||
for (let offset = 0; ; offset += PAGE) {
|
||||
const list = await listPhotos({ count: PAGE, offset, order: 'newest', merged: true });
|
||||
for (const p of list) {
|
||||
// `merged: true` can repeat a photo across file-rows; dedupe by UID
|
||||
// so the same tile doesn't render twice.
|
||||
if (seen.has(p.UID)) continue;
|
||||
seen.add(p.UID);
|
||||
const note = p.Caption?.trim();
|
||||
if (!note) continue;
|
||||
out.push({ photo: p, note });
|
||||
}
|
||||
if (list.length < PAGE) break;
|
||||
for (const p of data) {
|
||||
const note = p.Caption?.trim();
|
||||
if (!note) continue;
|
||||
out.push({ photo: p, note });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user