feat(photos): add Photos timeline view with lightbox and infinite scroll

Backend: new GET /api/photos endpoint with cursor-based pagination that
queries image/video files sorted by EXIF captured_at (falling back to
created_at), joining file_metadata for sort dates.

Frontend: dense photo grid grouped by day with lazy-loaded thumbnails,
IntersectionObserver infinite scroll, multi-select with batch
download/delete, and a full-screen lightbox with prev/next navigation,
EXIF metadata display, and download/favorite/delete toolbar.

Includes navigation wiring, CSS (with dark theme), and i18n translations
for all 9 locales.
This commit is contained in:
Jared Wolff
2026-03-05 13:40:02 -05:00
parent 69fe3a8b07
commit 53e4f5afe6
23 changed files with 1318 additions and 3 deletions
+30 -1
View File
@@ -73,7 +73,8 @@ const VIEW_FLAGS = {
'shared': 'isSharedView',
'recent': 'isRecentView',
'favorites': 'isFavoritesView',
'trash': 'isTrashView'
'trash': 'isTrashView',
'photos': 'isPhotosView'
};
/**
@@ -114,6 +115,11 @@ function setCurrentSection(section) {
if (section !== 'shared' && window.sharedView) {
window.sharedView.hide();
}
// Hide photosView when switching to any other section
if (section !== 'photos' && window.photosView) {
window.photosView.hide();
}
}
function switchToSharedView() {
@@ -223,7 +229,30 @@ function switchToRecentFilesView() {
}
}
function switchToPhotosView() {
setCurrentSection('photos');
// Hide breadcrumb
const breadcrumb = document.querySelector('.breadcrumb');
if (breadcrumb) breadcrumb.style.display = 'none';
// Hide actions-bar (photos has its own upload via selection bar)
window.setActionsBarMode('hidden');
// Hide file containers
const filesGrid = document.getElementById('files-grid');
const filesListView = document.getElementById('files-list-view');
if (filesGrid) filesGrid.style.display = 'none';
if (filesListView) filesListView.style.display = 'none';
// Show photos view
if (window.photosView) {
window.photosView.show();
}
}
window.switchToFilesView = switchToFilesView;
window.switchToSharedView = switchToSharedView;
window.switchToFavoritesView = switchToFavoritesView;
window.switchToRecentFilesView = switchToRecentFilesView;
window.switchToPhotosView = switchToPhotosView;