Drop the browser build; space works the transport; fix bulk track rename
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.
This commit is contained in:
@@ -2,55 +2,65 @@
|
||||
|
||||
Reads and edits BWF (Broadcast Wave) metadata for production sound: scene,
|
||||
take, timecode, track names, plus export, split, combine and a sound report.
|
||||
Two things get built from one source tree:
|
||||
|
||||
- `index.html` at the root: a single self-contained page, no server, no
|
||||
network, opens in a browser.
|
||||
- `mac-app/`: a native macOS app (Tauri v2 + Rust) that wraps the same page
|
||||
and adds real file access, a Rust audio engine and a Rust WAV writer.
|
||||
One thing gets built: `mac-app/`, a native macOS app (Tauri v2 + Rust) whose
|
||||
frontend is a single self-contained page, wrapping real file access, a Rust
|
||||
audio engine and a Rust WAV writer.
|
||||
|
||||
There used to be a second, browser-only page built from the same sources, and
|
||||
much of the shape of this repo still shows it — a vendored WordPress plugin
|
||||
patched on the way in, a `shim`/`bridge` split, tests that load a page into
|
||||
jsdom. It is gone. Don't build it, don't write for it, and don't reintroduce a
|
||||
`--tauri` flag or a second output: there is one page and one build.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
python3 build/build.py # writes ./index.html
|
||||
python3 build/build.py --tauri # writes ./mac-app/dist/index.html
|
||||
python3 build/build.py # writes ./mac-app/dist/index.html
|
||||
```
|
||||
|
||||
Both, every time: a change to shared code affects both pages, and a feature
|
||||
wired into only one looks exactly like a broken feature (a visible button that
|
||||
does nothing). There is a test for that specific trap.
|
||||
|
||||
The Mac app is built by double-clicking `mac-app/Build BWF Analyser.command`.
|
||||
That script regenerates the page, touches `main.rs` so the page is re-embedded
|
||||
(cargo does not reliably notice a changed `dist/`), compiles, assembles and
|
||||
signs the bundle.
|
||||
|
||||
`cargo build` on its own is not that. It produces the bare binary and leaves
|
||||
the bundle alone, so the `.app` sitting there is still the old one — which
|
||||
looks exactly like a change that didn't work.
|
||||
|
||||
**Restart the app after compiling it, every time, without being asked.** Quit
|
||||
the running copy and open the newly built one, so there is something on screen
|
||||
to try rather than a description of what should happen. A compiled-but-not-
|
||||
restarted app goes on showing the previous page and nothing in the window says
|
||||
so. Then **say in the reply that the app was rebuilt and relaunched**, and give
|
||||
the build stamp it should be showing — `window.BWFA_BUILD`, also on
|
||||
`data-bwfa-build`, and printed by the build script. Stating it is the point:
|
||||
it lets a mismatch be spotted from the reply instead of being mistaken for a
|
||||
broken feature.
|
||||
|
||||
## Test
|
||||
|
||||
```bash
|
||||
node build/test.js # the browser page, in jsdom
|
||||
node build/test-tauri.js # the Mac page against a stubbed engine
|
||||
node build/test-tauri.js # the page against a stubbed engine
|
||||
node build/test-export.js # every export/split/combine/format combination
|
||||
node build/test-play.js # playback maths, peaks, spectrogram, meters
|
||||
node build/test-restore.js build/test-framerate.js build/test-pdf.js
|
||||
BWF_TINY_CHUNKS=1 node build/test-tauri.js # tiny-read paths
|
||||
```
|
||||
|
||||
All of them should pass before anything ships. Roughly 370 checks.
|
||||
All of them should pass before anything ships. Roughly 420 checks.
|
||||
|
||||
## How the build works, and its traps
|
||||
|
||||
`build/build.py` inlines CSS and JS into one HTML file. The app's JavaScript
|
||||
(`build/src/bwf-analyser-app.js`) is vendored from a WordPress plugin and is
|
||||
kept pristine: changes to it are made as **exact-string patches** in lists in
|
||||
`build.py` (`SHARED_APP_JS_PATCHES`, `APP_JS_PATCHES`, `PLAYER_PATCHES`,
|
||||
`SPECTRO_PATCHES`, `MIXER_PATCHES`). Each patch asserts its anchor is found
|
||||
exactly once, so a stale anchor fails the build loudly rather than silently
|
||||
doing nothing.
|
||||
`build.py` (`BASE_APP_JS_PATCHES`, `APP_JS_PATCHES`, `PLAYER_PATCHES`,
|
||||
`SPECTRO_PATCHES`, `MIXER_PATCHES`, `TRANSPORT_KEY_PATCHES`). A patch whose
|
||||
anchor has gone stops the build rather than silently doing nothing.
|
||||
|
||||
- Patch strings are Python **non-raw** triple-quoted strings, so tabs in the
|
||||
JavaScript are written `\t`. Get this wrong and the anchor never matches.
|
||||
- `SHARED_*` patches apply to both builds; the others only to `--tauri`.
|
||||
- When inserting into the page, use the **last** `</body>`, not the first: the
|
||||
page contains inlined JavaScript that writes HTML, and the first match is
|
||||
inside a string literal.
|
||||
@@ -84,8 +94,12 @@ area, that a grid is scrambled, or that an element collapsed to zero width.
|
||||
Every one of those has shipped at least once. Layout changes need a screenshot
|
||||
from the user; keep them small and ask.
|
||||
|
||||
**Two pages, one behaviour.** If a feature only makes sense on the Mac build,
|
||||
it still needs to not look broken on the other one.
|
||||
**"Is a modal on screen" needs both markers.** `.modal` is `display: none`
|
||||
without `.open`, and closing does not always take `.open` back off — so a
|
||||
modal that has been opened once and shut again still carries it. Neither the
|
||||
class nor the `hidden` attribute answers the question alone:
|
||||
`.modal.open:not([hidden])` does. Modals also stack (the mixer opens over the
|
||||
file sheet), so "something else is open" says nothing about what is in front.
|
||||
|
||||
**The page stamps itself.** `window.BWFA_BUILD` holds the build time, also on
|
||||
`data-bwfa-build` on the app root. Use it to settle "is the app running the
|
||||
@@ -105,7 +119,7 @@ attribute.
|
||||
|
||||
```
|
||||
build/
|
||||
build.py assembles both pages, holds all the patches
|
||||
build.py assembles the page, holds all the patches
|
||||
body.html markup
|
||||
overrides.css the app's own styling on top of the plugin's
|
||||
l10n.json every string, plus hints
|
||||
|
||||
Reference in New Issue
Block a user