feat: filter sidebar, ingest progress, starred photos
- Left filter sidebar: All Photos / Favorites / Date by Year / Tags / Collections with counts, See more/less toggles, and blue active-row highlight - SSE ingest badge in header: pulsing dot + filename + indexed count during scan; auto-refreshes the library when a scan finishes - Starred/Favorites: starred column on photos, star button in lightbox toolbar, Favorites row in sidebar, ?starred=1 filter on /api/photos - GET /api/library/stats endpoint (totals, years, tags, collections) - GET /api/ingest/stream SSE endpoint (polls ingest_status table every 1.5s) - Worker writes ingest_status (active, current file, scanned count) to SQLite Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
4df32f9f32
commit
f0e237ab2b
10 files changed
+541
-127
No files matched your search
@@ -10,7 +10,7 @@ const json = (body) => ({
|
||||
});
|
||||
|
||||
// Library
|
||||
export function fetchPhotos({ cursor, limit = 100, q, from, to, tagId, collectionId } = {}) {
|
||||
export function fetchPhotos({ cursor, limit = 100, q, from, to, tagId, collectionId, starred } = {}) {
|
||||
const p = new URLSearchParams({ limit });
|
||||
if (cursor) p.set('cursor', cursor);
|
||||
if (q) p.set('q', q);
|
||||
@@ -18,6 +18,7 @@ export function fetchPhotos({ cursor, limit = 100, q, from, to, tagId, collectio
|
||||
if (to) p.set('to', to);
|
||||
if (tagId) p.set('tagId', tagId);
|
||||
if (collectionId) p.set('collectionId', collectionId);
|
||||
if (starred) p.set('starred', starred);
|
||||
return api(`/api/photos?${p}`);
|
||||
}
|
||||
|
||||
@@ -29,7 +30,19 @@ export function fetchMapPhotos() {
|
||||
return api('/api/photos/map');
|
||||
}
|
||||
|
||||
export function fetchLibraryStats() {
|
||||
return api('/api/library/stats');
|
||||
}
|
||||
|
||||
export function toggleStar(id, starred) {
|
||||
return api(`/api/photos/${id}`, { method: 'PATCH', ...json({ starred }) });
|
||||
}
|
||||
|
||||
// Tags
|
||||
export function fetchTags() {
|
||||
return api('/api/tags');
|
||||
}
|
||||
|
||||
export function addTag(photoId, name) {
|
||||
return api(`/api/photos/${photoId}/tags`, { method: 'POST', ...json({ name }) });
|
||||
}
|
||||
@@ -55,11 +68,6 @@ export function removeFromCollection(photoId, collectionId) {
|
||||
return api(`/api/photos/${photoId}/collections/${collectionId}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
// Tags + collections (for filter dropdowns)
|
||||
export function fetchTags() {
|
||||
return api('/api/tags');
|
||||
}
|
||||
|
||||
// Duplicates
|
||||
export function fetchDuplicates() {
|
||||
return api('/api/duplicates');
|
||||
|
||||
Reference in new issue
Block a user