67f15bffb7c73884fbc571f0bb84fc42eabd83b7
Collections synced their names and arrived empty on every device. The names are keyed on a uuid and worked; the membership union was keyed on `images.content_hash`, and the schema says plainly what that column is: "computed only when something needs it (import dedup, reconnect-by-hash), never in a scan". A library that has only ever been scanned has one for no image at all, so the join matched nothing and `WHERE ri.content_hash IS NOT NULL` discarded whatever survived. The union could never have moved a single row. Measured on a real catalog: 23,174 images, content hashes for 0 of them, `oc:fileid` for all 23,174, twelve collections, zero members. So membership now resolves through the file id first, exactly as keyword assignment already did — `ASSIGN_BY_FILE_ID` was added for this same reason and its doc comment even notes that membership was still on the hash. It is recorded for every image the moment a remote scan sees it, survives server-side rename and move (FR-NC-5), is the same integer on every device pointed at one Nextcloud, and is already what the thumbnail shards are keyed by. The content-hash union is kept rather than replaced: a local-only library has no `remote` rows, and where a hash has been computed it is a true identity that survives a library moving between servers. Both statements run; `INSERT OR IGNORE` against the primary key makes the overlap free. This repairs the merge. It cannot invent membership that no device recorded — where the rows were never written, collections stay empty until they are filled in again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DarkRoom
A cross-platform, non-destructive RAW photo editor for Linux and Android.
Status: early. v0.1 is a remote library viewer — see docs/milestone-v0.1.md.
Documentation
| Document | Contents |
|---|---|
| requirements.md | What the software must do — 122 numbered requirements |
| architecture.md | How it is built — crates, GPU pipeline, data model, sync |
| milestone-v0.1.md | The first buildable milestone |
Building
Desktop:
cargo run -p darkroom-desktop
Android (containerised toolchain, see docker/android):
./docker/android/build.sh cargo ndk -t arm64-v8a build --release
Current state
Working: workspace, GPU context and compute pass, adaptive Slint shell, Android cross-compilation of the core crates.
Not yet working: the zero-copy display path. The build currently uploads frames through the CPU, which is exactly what ARCH §6.1 forbids — measured at 96% of frame time at 4K. Replacing it is spike S1, the project's highest priority.
cargo run -p dr-gpu --example bench --features readback
reproduces that measurement.
Licence
GPL-3.0-or-later.
Releases
20
DarkRoom 0.24.0
Latest
Languages
Rust
86.1%
Slint
10.3%
Python
1.1%
Shell
1%
WGSL
0.9%
Other
0.6%