From 14a1b4e54e877a1fdd8054e4caf419a491f8052d Mon Sep 17 00:00:00 2001 From: dtoro Date: Sat, 6 Jun 2026 20:17:13 +0200 Subject: [PATCH] frontend: route all photo queries through sidecar timeline proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - listPhotos → /api/sidecar/timeline (was /photos) - countPhotos → /api/sidecar/timeline (was /photos) - hasPhotosMatching → /api/sidecar/timeline (was /photos) - Sidecar handler forwards X-Count header for countPhotos() - Sidecar adjusts X-Count to reflect post-filtered count --- sidecar/handlers_photos.go | 6 ++++++ web/src/lib/services/photoprism.ts | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sidecar/handlers_photos.go b/sidecar/handlers_photos.go index d92a4c6..5d393a5 100644 --- a/sidecar/handlers_photos.go +++ b/sidecar/handlers_photos.go @@ -39,6 +39,10 @@ func handlePhotos(pp *ppClient) gin.HandlerFunc { // If the user has no BasePath (admin/empty), return as-is. if basePath == "" { + // Forward PhotoPrism's X-Count header for countPhotos(). + if count := resp.Header.Get("X-Count"); count != "" { + c.Header("X-Count", count) + } c.JSON(http.StatusOK, photos) return } @@ -62,6 +66,8 @@ func handlePhotos(pp *ppClient) gin.HandlerFunc { } } + // Forward X-Count header adjusted to the filtered count. + c.Header("X-Count", itoa(len(filtered))) c.JSON(http.StatusOK, filtered) } } \ No newline at end of file diff --git a/web/src/lib/services/photoprism.ts b/web/src/lib/services/photoprism.ts index 482b9e8..2461fc7 100644 --- a/web/src/lib/services/photoprism.ts +++ b/web/src/lib/services/photoprism.ts @@ -144,7 +144,7 @@ export interface ListPhotosParams { } export async function listPhotos(params: ListPhotosParams = {}): Promise { - const { data } = await http.get('/photos', { + const { data } = await http.get('/api/sidecar/timeline', { params: { count: 60, offset: 0, @@ -260,7 +260,7 @@ export async function listPhotosAround(p: AroundParams): Promise { */ export async function countPhotos(q: string, opts: { merged?: boolean } = {}): Promise { const merged = opts.merged ?? false; - const resp = await http.get('/photos', { + const resp = await http.get('/api/sidecar/timeline', { params: { count: 10000, offset: 0, merged, q } }); // PhotoPrism's `X-Count` header counts SQL file rows (one row per @@ -636,7 +636,7 @@ export async function aggregateKeywords(): Promise { } async function hasPhotosMatching(q: string): Promise { - const resp = await http.get('/photos', { + const resp = await http.get('/api/sidecar/timeline', { params: { count: 1, offset: 0, q } }); return Array.isArray(resp.data) && resp.data.length > 0;