- duplicates: restrict the /library/duplicates/groups query to photos whose
folder path actually lives under an active SourceRoot in the user's
settings. Nextcloud's "move to trash" flow was leaving .delete/purge-1
Folder rows wired to the original source_root_id, leaking those entries
into the Duplicates view as ghost paths that the user never opted into.
- discard: add a spinner to the "Delete N" and "Empty discard pile"
buttons (and their confirm dialogs) while the destructive mutation is
in flight, so the user gets immediate feedback for a slow operation.
- timeline: render a bottom-of-grid "Loading more photos…" indicator
while usePhotosQuery's background cursor loop is still pulling pages.
Backed by a tiny Zustand store the loop drives via a balanced
start/stop (counter, not boolean, so rapid filter changes can't flip
the flag false while a fresh loop is alive).
- remove client-side upload UI + /upload endpoint. Nextcloud is the
authoritative ingress now; the duplicate path created confusion and
the backend route is gone too.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>