Deep-link view settings survive file drops
Dropped files ignored pins while the URL still claimed them, so the census venue replaced the demo's pinned room. Drop loads now inherit venueSel/viz from the query, and stale bank addressing (song/seed/frame/warm) is cleared on drop while view settings stay.
This commit is contained in:
+38
-3
@@ -104,7 +104,20 @@ async function loadFile(file, { seed = null, pins = null, frame = null, warm = n
|
||||
if (state.busy) return;
|
||||
state.busy = true;
|
||||
stopPlayback();
|
||||
|
||||
// A dropped file carries no pins of its own — inherit the view settings
|
||||
// from the URL (a demo deep-link's venueSel/viz), so the room and subject
|
||||
// you came to see survive the new track. The bank path always passes an
|
||||
// explicit pins object and is unaffected. Frame/warm never carry over:
|
||||
// they address the old song's timeline.
|
||||
const fromDrop = pins == null;
|
||||
if (fromDrop) {
|
||||
try {
|
||||
const q = new URLSearchParams(location.search);
|
||||
if (q.get('venueSel') || q.get('viz')) {
|
||||
pins = { venueSel: q.get('venueSel'), viz: q.get('viz') };
|
||||
}
|
||||
} catch { /* non-browser — no pins */ }
|
||||
}
|
||||
if (dom.overlay) {
|
||||
dom.overlay.hidden = true;
|
||||
dom.overlay.style.display = 'none';
|
||||
@@ -136,8 +149,8 @@ async function loadFile(file, { seed = null, pins = null, frame = null, warm = n
|
||||
// Deep link from a preview (filmstrip figure, venue-gallery card):
|
||||
// pins ride into load() so the arc builds pinned layers once, then
|
||||
// the exact frame with the probe's warm-up so stateful layers land
|
||||
// converged like the probe render. Dropped files never carry pins —
|
||||
// only `?song=` loads pass them.
|
||||
// converged like the probe render. Dropped files carry inherited
|
||||
// pins (above) but always start at frame 0.
|
||||
const deepLink = !!(pins && (pins.venueSel || pins.viz)) || Number.isFinite(frame);
|
||||
// Prime before the landing seek on deep-link loads: programs link
|
||||
// asynchronously and a draw against an unlinked program is wrong
|
||||
@@ -146,6 +159,7 @@ async function loadFile(file, { seed = null, pins = null, frame = null, warm = n
|
||||
if (deepLink) state.show.prime();
|
||||
seekTo(Number.isFinite(frame) ? frame : 0,
|
||||
Number.isFinite(warm) ? { warmup: warm } : {});
|
||||
if (fromDrop) clearBankParamsFromUrl();
|
||||
renderPanel();
|
||||
document.title = `flow-state · ${state.show.fileName}`;
|
||||
console.info('[flow-state]', describeLook(state.show.look));
|
||||
@@ -174,6 +188,27 @@ if (dom.changeTrack) dom.changeTrack.addEventListener('click', () => dom.fileInp
|
||||
dom.fileInput.addEventListener('change', (e) => {
|
||||
if (e.target.files[0]) loadFile(e.target.files[0]);
|
||||
});
|
||||
/**
|
||||
* A dropped file has no URL identity, so the bank addressing it by name
|
||||
* (?song=&seed=&frame=&warm=) must go once the file loads — otherwise the
|
||||
* URL keeps describing the previous song while another plays (and rerolls
|
||||
* would persist a seed against the wrong name). View settings
|
||||
* (?venue=&venueSel=&viz=) stay: they describe how you watch, not what.
|
||||
* Uses replaceState — no reload, no history spam.
|
||||
*/
|
||||
function clearBankParamsFromUrl() {
|
||||
try {
|
||||
const q = new URLSearchParams(location.search);
|
||||
if (!q.get('song') && !q.get('seed') && !q.get('frame') && !q.get('warm')) return;
|
||||
q.delete('song');
|
||||
q.delete('seed');
|
||||
q.delete('frame');
|
||||
q.delete('warm');
|
||||
const rest = q.toString();
|
||||
history.replaceState(null, '', rest ? `${location.pathname}?${rest}` : location.pathname);
|
||||
} catch { /* non-browser or sandboxed iframe */ }
|
||||
}
|
||||
|
||||
/**
|
||||
* `?song=centre` — open a bank song straight from a debug page.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user