Fixing some bugs in the UI
2 changed files+16−15
index.htmlmodified+4−4View file
@@ -245,14 +245,14 @@
245245 <button type="button" class="chip" id="mode-simulate" aria-pressed="true">Simulate</button>
246246 <button type="button" class="chip" id="mode-effort"
247247 title="Run several solver settings side by side on one clock">Compare computational effort</button>
248- <button type="button" class="chip" id="mode-vs-sphere" disabled title="Coming soon">Compare against sphere</button>
248+ <button type="button" class="chip" id="mode-vs-sphere" disabled title="Coming soon">Compare against sphere (Coming soon)</button>
249249 <button type="button" class="chip" id="mode-vs-upload"
250- title="Check this solver against a saved reference run.">
250+ title="Check this solver against a saved reference run">
251251 Compare against uploaded data</button>
252252 <input type="file" id="cmp-file" accept=".h5" hidden>
253253 </div>
254254 <div class="controls ctrl-group" data-group="surface">
255- <label>preset
255+ <label>reaction-diffusion model
256256 <select id="model"></select>
257257 </label>
258258 <label title="The surface the pattern is solved on. Swapping it does not recompile the solver or restart the run.">geometry
@@ -284,7 +284,7 @@
284284 <span id="cmp-fileinfo" class="stats" hidden></span>
285285 <button id="cmp-fileclear" hidden
286286 title="Drop the reference file and compare the variants against each other again">×</button>
287- <button id="cmp-start" class="primary">Compare</button>
287+ <button id="cmp-start" class="primary">Compile comparison</button>
288288 <span id="cmp-count" class="stats"></span>
289289 </div>
290290 <div class="controls ctrl-group" data-group="solver">
src/main.tsmodified+12−11View file
@@ -283,6 +283,10 @@ const geomSource = (): string => editedGeomSource ?? geometry.source;
283283 // ---------------------------------------------------------------- UI wiring
284284 function buildParamInputs(): void {
285285 elParams.replaceChildren();
286+ if (model.params.length === 0) return;
287+ const tag = document.createElement('label');
288+ tag.textContent = 'model parameters';
289+ elParams.append(tag);
286290 for (const spec of model.params) {
287291 const label = document.createElement('label');
288292 label.textContent = `${spec.label} `;
@@ -318,7 +322,7 @@ function buildGeomParamInputs(): void {
318322 elGeomParams.replaceChildren();
319323 if (geometry.params.length === 0) return;
320324 const tag = document.createElement('label');
321- tag.textContent = `${geometry.key}.m`;
325+ tag.textContent = 'geometry parameters';
322326 elGeomParams.append(tag);
323327 for (const spec of geometry.params) {
324328 // A random seed picks a draw and means nothing on its own, so it gets a
@@ -1422,13 +1426,10 @@ function setMode(mode: Mode): void {
14221426 return;
14231427 }
14241428 if (mode === 'compute-effort') {
1425- if (compareRun && refCase) {
1426- // A vs-upload study is actively running; leave it running, in its own
1427- // mode. Stop it first (Simulate, or the bar's own Stop) to switch.
1428- return;
1429- }
1430- // Only safe to drop a loaded file while nothing is using it — the same
1431- // guard elCmpFileClear itself observes (disabled while a study runs).
1429+ // Tear down whatever study is running first (mirrors Simulate above) —
1430+ // stopCompare's synchronous prefix disposes it and nulls `compareRun`
1431+ // before its first `await`, so `refCase` is safe to drop right after.
1432+ if (compareRun) void stopCompare();
14321433 if (refCase) {
14331434 refCase = null;
14341435 applyRefUi();
@@ -1464,8 +1465,8 @@ elCmpFile.addEventListener('change', () => {
14641465 // One click, one study: the file's own settings become the single
14651466 // variant — its recorded niter, its band, its dt undivided — and the
14661467 // comparison opens on them, paused at the initial state so what runs is
1467- // the user's choice. (Widening it is: stop comparing, pick more chips,
1468- // press Compare — the file stays loaded.)
1468+ // the user's choice. (Widening it is: teardown the comparison, pick more
1469+ // chips, compile it again — the file stays loaded.)
14691470 cmpSelected.niter.clear();
14701471 cmpSelected.niter.add(refCase.niter);
14711472 cmpSelected.lmax.clear();
@@ -1513,7 +1514,7 @@ function setCompareUi(on: boolean): void {
15131514 elCmpNiter.querySelectorAll('button').forEach((b) => (b.disabled = on));
15141515 elCmpLmax.querySelectorAll('button').forEach((b) => (b.disabled = on));
15151516 elCmpDt.querySelectorAll('button').forEach((b) => (b.disabled = on));
1516- elCmpStart.textContent = on ? 'Stop comparing' : 'Compare';
1517+ elCmpStart.textContent = on ? 'Teardown comparison' : 'Compile comparison';
15171518 // The movie bar's own hidden flag is independent of the movie *group's* —
15181519 // force it closed so it doesn't reappear open once the group is shown
15191520 // again on returning to Simulate.