From 34ac2f14d3b119b6aad1841c9cd0595a6f0917ba Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 20 Sep 2026 21:04:10 +0200 Subject: [PATCH] Sync faces and the catalog before thumbnails, so a fresh device sees its names and collections first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The thumbnail stage ran first and, on a device that had just adopted its peers' shards, spent its time re-uploading hundreds of megabytes under its own client id while faces, people, collections and dates waited behind it. Faces go first — the catalog merge assigns identities to faces this device holds — then the catalog, then thumbnails. Co-Authored-By: Claude Opus 5 (1M context) --- ui/dr-ui/src/derived_sync.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ui/dr-ui/src/derived_sync.rs b/ui/dr-ui/src/derived_sync.rs index 4599e13..ff0c99c 100644 --- a/ui/dr-ui/src/derived_sync.rs +++ b/ui/dr-ui/src/derived_sync.rs @@ -198,9 +198,13 @@ async fn run( // cheaper than probing, and an existing folder is not an error. let _ = backend.create_dir(&base).await; - let _ = tx.send(SyncMessage::Status("checking thumbnails…".into())); - sync_shards(backend, &base, thumbs_dir, scratch, &mut report).await?; - + // Small before large, and what the user is waiting for before what + // fills in behind them. Faces first because the catalog merge assigns + // identities to faces this device holds, so they must be here by then; + // the catalog next for collections, people and dates; thumbnails last, + // because a fresh device's thumbnail stage is hundreds of megabytes and + // everything queued behind it — the sidebar, the timeline, the names — + // was invisible for as long as it ran. let _ = tx.send(SyncMessage::Status("checking faces…".into())); sync_face_shards( backend, @@ -216,6 +220,9 @@ async fn run( let _ = tx.send(SyncMessage::Status("checking collections…".into())); sync_catalog(backend, &base, catalog_path, scratch, &mut report).await?; + let _ = tx.send(SyncMessage::Status("checking thumbnails…".into())); + sync_shards(backend, &base, thumbs_dir, scratch, &mut report).await?; + // TRACES: FR-UI-8 // Last, and it costs one small GET plus at most one small PUT. Last because // it is the only thing here that is not derived state and so the only thing