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:
@@ -51,6 +51,11 @@ pub struct FileDto {
|
||||
/// Owner user ID (omitted from JSON when None)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub owner_id: Option<String>,
|
||||
|
||||
/// Sort date for Photos timeline — COALESCE(EXIF captured_at, created_at).
|
||||
/// Only populated by the /api/photos endpoint.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sort_date: Option<u64>,
|
||||
}
|
||||
|
||||
impl From<File> for FileDto {
|
||||
@@ -73,6 +78,7 @@ impl From<File> for FileDto {
|
||||
category: Arc::from(category_for(name, mime)),
|
||||
size_formatted: format_file_size(size),
|
||||
owner_id: file.owner_id().map(String::from),
|
||||
sort_date: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,6 +118,7 @@ impl FileDto {
|
||||
category: Arc::from("Document"),
|
||||
size_formatted: "0 Bytes".to_string(),
|
||||
owner_id: None,
|
||||
sort_date: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user