fix(venue): fly in once per set, not before every song (#978)
ship-ci / ci (push) Waiting to run

Tester, mid-gig: "the second song in the gig started when the first one ended.
But it showed the flyover intro again."

The flyover is arriving at the venue, and you arrive once. #968 stopped it
replaying on an arrangement SWITCH (same filename), but a gig's song 2 is a
genuinely different file, so it took the full-teardown path and played the
arrival flyover again — the camera flew in from the back of the room before
every track of the set.

The play queue now answers isContinuation(): false for the first song of a set
(or a standalone play — an arrival), true for song 2..N. onSongLoaded carries
the room over to the new song's loop on a continuation, and only a real arrival
plays the intro.

Verified on the built AppImage: isContinuation goes false (song 1) -> true
(song 2) across an advance, and song 2 no longer flies in.

Also confirmed NOT a bug, same session: "didn't show the author for the second
song." The credits card shows on a queue advance whenever the song carries
authors — reproduced with a song that has them as the advanced-to track. The
tester's song 2 simply had no `authors:` metadata (most auto-converted feedpaks
don't). No code change.

Tests: isContinuation across start/advance/clear, and that onSongLoaded gates the
flyover on the continuation check. Both fail on pre-fix source. JS 1214/1214.
This commit is contained in:
Byron Gamatos
2026-07-15 12:39:25 +02:00
committed by GitHub
parent e14ef64224
commit 2f2a095e4c
4 changed files with 62 additions and 1 deletions
+19
View File
@@ -117,3 +117,22 @@ test('a throwing document does not take the venue down with it', () => {
global.document = prev;
}
});
// The arrival flyover must NOT replay for songs 2..N of a set. onSongLoaded
// consults the play queue: a continuation (gig/album/playlist song 2+) carries
// the room over with a loop crossfade, only an arrival plays the intro.
test('a set continuation carries the room over instead of re-flying-in', () => {
const fs = require('node:fs');
const path = require('node:path');
const src = fs.readFileSync(path.join(__dirname, '..', '..', 'static', 'v3', 'venue-crowd.js'), 'utf8');
const start = src.indexOf('function onSongLoaded(');
const open = src.indexOf('{', src.indexOf(')', start));
let depth = 1, i = open + 1;
while (i < src.length && depth > 0) { const ch = src[i]; if (ch === '{') depth++; else if (ch === '}') depth--; i++; }
const fn = src.slice(start, i);
const contIdx = fn.search(/_isSetContinuation\s*\(\s*\)/);
const introIdx = fn.search(/playIntro\s*\(/);
assert.ok(contIdx !== -1, 'onSongLoaded must consult the set-continuation signal');
assert.ok(introIdx !== -1, 'the intro must still exist for a real arrival');
assert.ok(contIdx < introIdx, 'the continuation check must gate the flyover — a set song 2+ must not fly in');
});