mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 11:19:24 +00:00
feat(career): extract the whole setlist before the gig starts
A feedpak is a zip, and the first play of one pays for its extraction into
sloppak_cache. Inside a set that cost landed BETWEEN songs: the player finished
a number and then sat there waiting for the next one to unpack, mid-gig.
A setlist is a known list up front, so unpack it all while the poster is still on
screen. New POST /gigs/prepare walks the set through resolve_source_dir; the
poster's Play button shows "Preparing set…" while it runs.
Best-effort by design, at every level:
- a corrupt pak in the set does not sink the prepare (it is reported in
`failed`; the play itself surfaces the error exactly as it does outside a
gig — slow beats blocked)
- a host without the library resolvers degrades to a no-op rather than 500
- a failed request just falls through to the old lazy extraction
Ordering matters and is pinned: the set is unpacked BEFORE the stage is borrowed
(venue/viz overwritten) and before the queue starts, so a proposal cancelled
while unpacking leaves nothing half-applied to unwind.
Tests unpack REAL zips rather than mocking the extractor: every song of the set
lands on disk before the first note, a re-prepare does not duplicate the unpack,
one bad pak still leaves the good one prepared, and no-library / empty-setlist
degrade cleanly. 18/18.
NB the other half of the gig report — the per-song results popup interrupting
the set (and worse, claimAutoExit'ing so the queue would not advance until it was
dismissed) — is fixed in the note_detect plugin repo, which is not part of this
checkout.
This commit is contained in:
@@ -1123,10 +1123,40 @@
|
||||
sfx('page');
|
||||
}
|
||||
|
||||
function startGig() {
|
||||
// Unpack the whole set before the first note.
|
||||
//
|
||||
// A feedpak is a zip, and the first play of one pays for its extraction. In
|
||||
// a set that cost landed BETWEEN songs: the player finished a number and
|
||||
// then sat there waiting for the next one to unpack, mid-gig. The setlist is
|
||||
// known up front, so warm it all while the poster is still on screen.
|
||||
//
|
||||
// Best-effort by design: a library that won't pre-extract must not stop the
|
||||
// gig from starting — the play itself surfaces the error the same way it
|
||||
// does outside a gig. Slow is better than blocked.
|
||||
async function prepareGigSongs(prop, btn) {
|
||||
const label = btn && btn.textContent;
|
||||
if (btn) { btn.disabled = true; btn.textContent = 'Preparing set…'; }
|
||||
try {
|
||||
await fetch(`${API}/gigs/prepare`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ songs: prop.songs.map((s) => s.filename) }),
|
||||
});
|
||||
} catch (_) { /* start anyway — first play will extract as it always did */ }
|
||||
if (btn) { btn.disabled = false; if (label) btn.textContent = label; }
|
||||
}
|
||||
|
||||
async function startGig(btn) {
|
||||
const prop = _ppGigProposal;
|
||||
const q = window.feedBack && window.feedBack.playQueue;
|
||||
if (!prop || !q || typeof q.start !== 'function' || typeof window.playSong !== 'function') return;
|
||||
|
||||
// Extract the setlist BEFORE the stage is borrowed and the queue starts,
|
||||
// so a failure here leaves nothing half-applied to unwind.
|
||||
await prepareGigSongs(prop, btn);
|
||||
// The poster's Play could have been cancelled while we were unpacking.
|
||||
if (_ppGigProposal !== prop) return;
|
||||
|
||||
// The gig BORROWS the stage: stash whatever venue/viz the user had so
|
||||
// the set ending gives it back (unlike "Play here", which is an
|
||||
// explicit persistent choice on the venue card).
|
||||
@@ -1424,7 +1454,7 @@
|
||||
}
|
||||
const gigBtn = e.target.closest('[data-pp-gig]');
|
||||
if (gigBtn) { bookGig(gigBtn.dataset.ppGig); return; }
|
||||
if (e.target.closest('[data-pp-gig-play]')) { startGig(); return; }
|
||||
if (e.target.closest('[data-pp-gig-play]')) { startGig(e.target.closest('[data-pp-gig-play]')); return; }
|
||||
if (e.target.closest('[data-pp-gig-reroll]')) {
|
||||
if (_ppGigProposal) bookGig(_ppGigProposal.genre_key);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user