feat(diashow): guarantee all eligible photos shown + 2048px display derivative
Diashow completeness rewrite so every eligible upload is shown regardless of
bursts, disconnects, or library size:
- queue.ts: SlideQueue with live/shuffle queues, allKnown map, recentlyShown
ring; merge(dedup, live-first), remove/removeByUser (prunes recentlyShown),
knownIds for reconcile-eviction. Adds queue.test.ts (burst/completeness/race).
- diashow/+page.svelte: reconcile (full paginate + evict, pre-scan snapshot to
spare concurrent uploads) on mount/reconnect/periodic; catchUpNew paginate-
until-known for bursts with debounced maxWait; hard-cut removals; decode
timeout + candidate fallback + bounded skip so a broken image never stalls.
New ~2048px "display" derivative for big-screen sharpness, decoupled from the
data-saver preview (800px) used on phones:
- migration 016: upload.display_path + v_feed rebuilt (DROP+CREATE, not REPLACE,
to slot the column beside preview/thumbnail).
- compression: generate_image_derivatives emits preview+display (downscale-only
guard, no upscaling); backfill_missing_display regenerates on startup (safe:
logs on error, never soft-deletes).
- upload.rs/main.rs: GET /upload/{id}/display (mirrors preview auth/cache),
/media/displays direct-serve blocked.
- feed.rs + types.ts: display_url in feed/delta DTOs.
- diashow candidate chain: display -> original -> preview.
Verified on the running stack: migration applied, 10/10 existing images
backfilled (2048px cap honoured, small images not upscaled), /display serves
200, /feed returns display_url, diashow cycles.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,7 @@ pub struct VisibleMedia {
|
||||
pub original_path: String,
|
||||
pub preview_path: Option<String>,
|
||||
pub thumbnail_path: Option<String>,
|
||||
pub display_path: Option<String>,
|
||||
pub mime_type: String,
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ impl Upload {
|
||||
id: Uuid,
|
||||
) -> Result<Option<VisibleMedia>, sqlx::Error> {
|
||||
sqlx::query_as::<_, VisibleMedia>(
|
||||
"SELECT up.original_path, up.preview_path, up.thumbnail_path, up.mime_type
|
||||
"SELECT up.original_path, up.preview_path, up.thumbnail_path, up.display_path, up.mime_type
|
||||
FROM upload up
|
||||
JOIN \"user\" u ON u.id = up.user_id
|
||||
WHERE up.id = $1 AND up.deleted_at IS NULL
|
||||
@@ -134,6 +135,19 @@ impl Upload {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_display_path(
|
||||
pool: &PgPool,
|
||||
id: Uuid,
|
||||
display_path: &str,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
sqlx::query("UPDATE upload SET display_path = $2 WHERE id = $1")
|
||||
.bind(id)
|
||||
.bind(display_path)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_thumbnail_path(
|
||||
pool: &PgPool,
|
||||
id: Uuid,
|
||||
|
||||
Reference in New Issue
Block a user