crates/ui-egui/src/panels/left/folders.rs: main's built-in-place guard around Rename and Move kept; the Move item is the PR's move_folder_item inside it.
docs/parity-checklist.md: the PR's edits to its rows applied to main's rows.
docs/whats-new.md: the PR's entry added under the 2026-10-29 heading.
docs/parity-checklist.md: the PR's edit to the LRC-LIB-CATALOG-SWITCH row applied to main's row.
docs/whats-new.md: the PR's 2026-10-29 section added above main's sections.
docs/parity-checklist.md: header keeps main's newer date plus the PR's item; the PR's edit to the LRC-LIB-FOLDERS row applied to main's row; revision rows union, newest first.
docs/whats-new.md: the PR's 2026-10-28 section added above 2026-10-27.
crates/engine/src/import/job.rs: union of the imports (main's Seen, reusable_probes, sidecars_of plus the PR's FileFacts); the sidecar read uses main's batched found_sidecar and the PR's skip for duplicates with a known capture time.
crates/engine/src/import.rs, cmd/library.rs: main split these files; kept main's side here and ported the PR's hunks to import/job.rs, cmd/library/import.rs and cmd/library/specs.rs (module doc stays in import.rs).
docs: headers keep main's newer date plus the PR's item; the PR's row additions applied to main's rows; revision rows and What's New entries kept, one heading per date.
docs/parity-checklist.md: header keeps main's date plus the PR's item; the LR-IMP-ADD-DIALOG row keeps main's text and gets the PR's sentence; revision rows union.
docs/whats-new.md: both entries kept.
docs/gaps.md, docs/parity-checklist.md: header keeps the newer date plus both sides' items; revision row added newest first.
locales/ru.json: union of keys.
docs/gaps.md, docs/parity-checklist.md: kept main's header and rows, added the PR's video text and revision row.
crates/engine/src/lightroom_catalog.rs: the PR's two tests moved to lightroom_catalog/tests.rs (main split the module).
Dropped the PR's unrelated hunks (slide_overlay.rs, tests_export.rs, raw corpus tests) per the review.
Some Samsung panoramas have no end-of-image marker: the scan data runs
straight into the SEF trailer at the end of the file, so the header
check refused them as truncated, and jpeg-decoder (DCT-scaled previews)
and zune-jpeg both fail on the trailer's bytes after the scan.
When the file ends with a valid SEF trailer (SEFT, a directory length
that points at SEFH, a sane entry count, every entry's block inside the
file before SEFH) and no EOI is reached, the image is read as the bytes
before the earliest SEF block plus an EOI, for both the header and the
decode. The cut must fall in scan data after the first SOS; a JPEG cut
short without such a trailer is still refused.
A catalog photo whose bytes match another library photo got the generic develop defaults, so a raw
with no white balance or lens setting in the catalog lost its as-shot white balance and embedded
lens corrections and rendered unlike a file import. It now gets the import defaults (camera
defaults plus the default preset), as a file import does, before the catalog's settings go on top.
Show in Library selected the lowest mapped photo id, which can be a master left in Recently Deleted
whose new virtual copy the import added; All Photos doesn't show it. It now selects the lowest
mapped photo not in Recently Deleted, and the button is left out when there is none.
Tests: a content-duplicate raw with no catalog settings equals its camera defaults (as-shot WB,
lens profile on); Show in Library skips a trashed mapped photo and offers nothing when only
trashed or vanished ids are mapped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reasons Try Again and the launch check give for a missing remembered library are now in the
interface language (all 17 catalogs). A folder that can't be looked into (no permission, a share
that timed out) is no longer called gone: lightcraft_engine::library::library_state tells a missing
catalog from a failed lookup, and the window shows the system's reason.
Require a covering embedded image only for renderable import candidates. Keep the available camera JPEG for preview-only raws and failed or unavailable render fallbacks; ordinary quick views and grid thumbnails retain their immediate stand-in behavior. Also release import preview state when canceled through the control channel.
Co-Authored-By: Codex <noreply@openai.com>
Move Folder To… in the Folders and Local menus opened the folder dialog synchronously on the UI thread, so the window stopped drawing until it closed, and on Linux X11 the app could hang. Both menus now go through the shared picker, like Import and Move to Folder…: the dialog runs off the UI thread where the host can do that and folder.move runs when it closes. The "Moved; N photo(s) relinked" message is shown either way, now translated in both menus.
When the library last opened was missing at launch (its drive or network share not connected yet, or moved), LightCraft created an empty library at that path, seeded it with the demo photos and opened it. The launch plan now marks the library remembered in Settings, and when it holds no library the session opens nothing and the can't-open window offers Try Again, Choose Another Library, Continue Without Saving and Quit. The default location, --library and LIGHTCRAFT_LIBRARY are still created when missing, as before.
The engine now refuses these two commands for the home folder and its Pictures, Desktop and
Downloads, whoever asks (the app, a script, an agent). The check is a pure function of the path
and the home folder; the commands read the real home once.
The Home, Pictures, Desktop and Downloads rows carry a translated label. Rename Folder…
started its prompt with that label, so confirming it in German renamed ~/Pictures to
~/Bilder on disk, and Home was offered for rename at all. Local now lists no Rename Folder…
or Move Folder To… on a built-in place; a folder kept with Browse Folder… still renames
from its real name.
Where the folder listing can't vouch for a name (non-ASCII names, a listing that is gone), each photo's sidecar names are asked of the disk, nine per photo, one photo after another. The batch's lookups now run 16 at a time; the loop that plans the photos takes each one's answer in order.
They use the same `at_once` as the probe checks, so the latency stand-in measured with the previous commit applies to them as well (16 at a time against one at a time); the lookups themselves were not timed on a share for this version.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reusing a scan's probes costs one stat per file to see that it is as it was. They ran one after another, so on a network share every file waited for a round trip. They now run 16 at a time, in the import's batches and in the scan's check of an earlier scan's probes.
Measured on this version with each stat made to take 2 ms (a stand-in for a share's round trip): 5,990 stats took 15.1 s one at a time and 0.95 s through `stat_all`, with the answers in the same order. An earlier version of this change, tried on a real network share, spent most of the import's time in these stats; that figure is not repeated here because it was not taken on this code.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The restore actions use the recorded folder without checking that it still
exists, so an upgrade creates it again rather than using the default folder.
The probe asked for a file's size, read it (an open and its own size question), and then asked for its modification time again by path: three round trips to a network share's server for what one open can answer. It now opens the file once and takes the size and the modification time from the open file. What is read, the work-gate weight, and the text of the error for a file that can't be read are unchanged.