Drag a heading and the column moves, with a copy of it following the pointer
and the column it came from stepping back. One array of keys — every column,
shown or hidden — backs the table, the Settings list and what is saved, so a
hidden column keeps its neighbour and returns where it was rather than at the
end. A drag ends in a click, and the click is what sorting listens for, so
that click is swallowed.
Opening a folder loads its first file: the read, the peaks, the channel chips
and the waveform, then paused at the start rather than playing. playRow gained
a paused mode instead of a second loader that could drift from it. It cannot
stop a folder opening, and a file that will not decode no longer writes a
playback error over the line saying the folder opened — nobody asked it to
play. The badge follows the transport now, so a paused file stops claiming to
be playing.
A bulk run re-reads every file it touches, but nothing told the transport to
look again: rename the boom across a card and the mixer went on showing the
old name for the very file it had just rewritten.
Settings loses its Done button and the mixer its Close — both apply as you
touch them, and the window's own close is enough. Save Image moves onto the
file name's line; the rule meant to do that had been dead for some time,
overwritten by the shared modal header. The exported spectrogram carries the
folder, the file and the frequency axis, drawn in, because a PNG read
somewhere else has none of that. The viewer is unchanged.
Mixer track names wear the player's pill, the waveform thumbnails give their
grey panel back to the row, and every button is the transport's size.
Build output that had been committed by accident is untracked, and .gitignore
grows the entries for it.
459 checks.
The browser page is gone, with its shim, its shell CSS and its suite. build.py
has no --tauri flag and one output: the app's page. The patch lists lose the
SHARED_ prefix, which only ever meant "shared between the two builds", and
test-pdf.js was quietly loading the browser page — it reads the app's now.
Space plays and pauses, in the main window off the player at the bottom and in
the mixer off the same transport. It is swallowed rather than passed on: that
stops the window scrolling, and stops a focused button taking the same press as
a second activation, which toggles twice and looks like a dead key. Typing, and
any dialog other than the mixer, keep it. Deciding what is in front needs both
markers — closing does not always remove .open, and .modal without it is
display:none regardless of the hidden attribute.
The mixer footer put the next file's name adrift in the middle of the row. The
margin-left: auto meant to park it beside Close could do nothing, because the
framework's flex: 1 1 auto had both nav groups growing to fill the row and left
no free space to absorb. Pinned to flex: 0 0 auto. The file-detail modal shares
the markup and follows.
Bulk track rename wrote nothing, on every file, and had never worked. A rename
is keyed on the name it replaces rather than a path, so the frame-rate pass
threw reading edit.path off it — before any byte was written, so nothing was
corrupted, only untouched. The failure handler discarded the reason and the run
still ended on a tidy Done, which is why 0 saved read as progress; it now names
the file and the cause in the log.
429 checks. The gap that hid the rename bug was end-to-end: the writer was unit
tested and the panel rendered, and nothing drove one into the other.
Reads and edits BWF metadata for production sound. One source tree builds a
single self-contained page and a native Tauri app with a Rust audio engine and
WAV writer. Around 370 checks across seven test suites.
First commit of the existing state, so that from here every change can be
seen and undone.