//! TRACES: FR-CAT-4 | FR-NC-3 | NFR-P9 //! Drives the library grid from scan and thumbnail workers. //! //! Owns the bridge between three background activities and one single-threaded //! event loop: //! //! - a **scan** worker walking the remote tree into the catalog //! - a **thumbnail** worker range-fetching previews for visible cells //! - the **grid model** Slint renders //! //! Nothing here blocks. Workers post through mpsc channels drained by Slint //! timers, which is the same shape [`crate::launch_ui`] uses for login. //! //! # Why thumbnails are fetched, not derived from the scan //! //! A scan yields paths and sizes, nothing visual. Each thumbnail costs its own //! range request, so they are fetched **only for cells the grid actually //! wants** โ€” never for the whole library up front. On the reference library //! that is the difference between a few MB and ~370 GB (ARCH ยง6.7). //! //! Split into one module per area of behaviour (docs/dev/code-health.md CH-1): //! `controller` holds the running state every other module reads and writes //! through `pub(super)` fields; `open` is the launch-to-scan cycle and the //! worker that checks the catalog file before either touches it; `offline` //! is what of a collection is on this device and the prompt that offers to //! change it; `window` fills the grid model from the catalog and drains the //! thumbnail fetch; `sync` is the background passes that reach beyond the //! loaded window โ€” the metadata sweep, the whole-library thumbnail pass, and //! the exchange with the server; `ratings_keywords` applies a judgement or a //! keyword to a selection and queues the sidecar and XMP writes behind it; //! `timeline` is the capture-time sidebar and the photographer's place, //! which move together closely enough to live in one file; `grid` wires the //! grid's own callbacks โ€” the keyboard cursor, cell-size zoom, the routes //! into and out of develop; `filter_bar` wires the rating, people, date and //! offline-scope filters. `mod.rs` re-exports what the rest of the crate //! calls by `library_ui::` path, so nothing outside this module needs to //! change. mod controller; mod filter_bar; mod grid; mod offline; mod open; mod ratings_keywords; mod sync; mod timeline; mod window; pub use controller::LibraryController; pub use grid::wire; pub(crate) use open::{forget_catalog, show_catalog_now, start_rescan}; pub use open::{open, reload}; pub use ratings_keywords::paste_settings_to_selection; pub(crate) use ratings_keywords::{save_judgements, start_sidecar_writes}; pub use timeline::format_date; pub use window::refresh_thumbnail;