Skip to content

Paint the Extract row from one place, so All cannot lie - #660

Merged
thcp merged 1 commit into
mainfrom
fix/extract-all-button-658
Sep 22, 2026
Merged

thcp merged 1 commit into
mainfrom
fix/extract-all-button-658

Conversation

@thcp

@thcp thcp commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Closes #658

Two stems selected, All lit, on every page load. Reported as part of #657.

What was wrong

The Extract row has three controls describing one fact, which stems will be extracted: the six chips, the All button, and the Lead + Backing toggle that only means anything while Vocals is among them. Each was painted by whoever happened to change the selection, and the paths did not agree.

All was synced from a closure inside wireAllButton, reachable only from a click. Both paths that set the selection without one left it stale:

  • The restore on load. stemSelectionReady resolves after the wiring has already synced once against the all-stems default, so the chips get the stored value and All keeps the default.
  • Opening a track from the library. applyStoredStemSelection set aria-pressed on each chip by hand and never touched All.

The Lead + Backing toggle had the same gap on the same two paths, which is how it stayed on screen offering a choice about vocals nobody was extracting.

What changed

The painting moves to static/js/stemChoice.js and every path calls it. main.js imports catalog.js, so catalog.js cannot import back into main.js; a module outside both is what lets them agree without a cycle.

All is now derived on every refresh from selectedStems.size === STEM_NAMES.length rather than kept in step by hand. That is the part that makes the next path added get it right without knowing this bug existed.

No behaviour changes beyond the fix: pressing All still fills and empties the row, and clicking a chip from the default state still switches to "only this stem".

How it was found

Against a real import rather than the seeded fixture, which cannot reach applyStoredStemSelection because it has no audioStems. Chose vocals and drums, ran a split, watched All go correctly dark, reloaded, and found it lit again with the same two chips.

Tests

Four in a new spec, seeding the store the way an earlier session would have left it. Two of them fail without this change: the All button's, and the toggle's. The other two pin the behaviour that was already right, so a future tidy-up of this row cannot quietly drop it.

Verified

The full Playwright suite (187 passing), pytest (1078 passing), the JS unit tests, node --check over every module, i18n coverage clean, uv.lock untouched.

Not in this PR

#659, the two different controls both labelled "All", which is the other half of what #657 reported. That one is a rename across ten language tables and a layout question, not a bug.

Two stems selected, All lit, on every page load (#658).

The Extract row has three controls describing one fact: the six stem chips,
the All button beside them, and the Lead + Backing toggle that only means
anything while Vocals is among them. Each was painted by whoever happened to
change the selection, and the paths did not agree.

All was synced from a closure inside wireAllButton, reachable only from a
click. So both paths that set the selection without one left it stale. The
restore on load arrives asynchronously, after the wiring has already synced
once against the all-stems default, so the chips get the stored value and All
keeps the default. Opening a track from the library set aria-pressed on each
chip by hand and never touched All at all. The Lead + Backing toggle had the
same gap on the same two paths, which is how it stayed on screen offering a
choice about vocals nobody was extracting.

So the painting moves to stemChoice.js and every path calls it. main.js
imports catalog.js, so catalog.js cannot import back into main.js; a module
outside both is what lets them agree without a cycle. All is now derived on
every refresh from selectedStems.size === STEM_NAMES.length rather than kept
in step by hand, which is the part that makes the next path added get it right
for free.

Reproduced first against a real import rather than the seeded fixture, which
cannot reach applyStoredStemSelection: chose vocals and drums, split, watched
All go correctly dark, reloaded, and found it lit again with the same two
chips. Both of those paths are now covered by tests that fail without this
change, along with the toggle's half and the All button's own behaviour.

Verified: the full Playwright suite (187), pytest (1078), the JS unit tests,
node --check over every module, i18n coverage clean, uv.lock untouched.
@thcp
thcp merged commit 6ff3076 into main Sep 22, 2026
10 checks passed
@thcp
thcp deleted the fix/extract-all-button-658 branch September 22, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The Extract "All" button lights up when only some stems are selected

1 participant