Let a manual collection be put in the order it is meant to be seen in
`collection_members.position` and `Sort::CollectionPosition` have been in the catalog since collections were, and nothing above dr-catalog has ever written or read either: `collections::set_order` had no callers, and the grid ordered everything by capture time whatever it was scoped to — dr-ui does not construct a `Query` at all, it has its own `GRID_ORDER` constant. So a manual collection was a set with an order nobody could see or change. Three pieces, because it could not be fewer: `grid_order_for` decides the ordering from the scope, and both readers take it from there. That is the load-bearing part. An ordinal only names a photograph relative to an ordering, so the window read and the span read have to agree — a shift-click resolved through a different ORDER BY than the cells were drawn with selects a different run than the one on screen, and the user finds out when the export runs. `read_ids_span` already stated that invariant about `GRID_ORDER`; this widens it to an ordering that depends on the scope. Only a single manual collection has one. A set draws its descendants' images too, and two children's positions are unrelated integers that interleave arbitrarily; a smart collection has no member rows to carry a position at all. Both fall back to capture time and refuse the drop rather than pretending. The drop is on the cell, on whichever half of it the finger landed — the trailing edge is the only way to name the last place in a collection, since there is no cell beyond the last one to drop in front of. `reordered` is pure and the membership is rewritten whole. `set_order` sets the positions it is given and leaves the rest, so a partial write would interleave the moved run with rows nobody touched; and it is read unfiltered, so what the filter is hiding keeps its place relative to what the user can see. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -477,6 +477,23 @@ pub fn collections_for_image(
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
/// What kind of collection `id` is, or `None` if there is no such collection.
|
||||
///
|
||||
/// Cheaper than reading the whole [`Collection`] where the caller only needs to
|
||||
/// know whether member rows exist — the grid asks this to decide whether manual
|
||||
/// position is a thing it can order by, and a smart collection has no
|
||||
/// `collection_members` rows to carry one.
|
||||
pub fn kind(conn: &Connection, id: CollectionId) -> Result<Option<CollectionKind>, CatalogError> {
|
||||
let found = conn
|
||||
.query_row(
|
||||
"SELECT kind FROM collections WHERE id = ?1 AND deleted = 0",
|
||||
[id.0 as i64],
|
||||
|r| r.get::<_, i64>(0),
|
||||
)
|
||||
.optional()?;
|
||||
Ok(found.map(CollectionKind::from_i64))
|
||||
}
|
||||
|
||||
/// A collection and everything beneath it, including itself.
|
||||
///
|
||||
/// Used for cycle checks and for scoping the grid to a parent: selecting a
|
||||
|
||||
Reference in New Issue
Block a user