mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 11:19:24 +00:00
Fix tuner auto-open flash: opt-in + persist (issue E, stage 1/3) (#655)
The tuner self-closes on song:play; autoplay fires it right after a song switch, so an auto-opened tuner flashed shut ~1s later. An arrangement switch (which never arms autoplay) instead persisted — the opposite tester reports, and not the mic. - New opt-in setting autoOpenOnTuningChange (tuner Settings, default OFF) - An auto-opened tuner persists: it ignores the autoplay song:play, stray outside-clicks, and same-screen re-emits, closing only via the new in-panel x / Skip buttons or leaving the song. A manual open keeps the classic click-away / play-to-close behaviour. - Adds the panel's first in-box close (x + contextual Skip). - All in the tuner plugin; no core app.js changes. Default (opt-in vs opt-out) is teed up for Byron to flip one boolean. Staged follow-ups: E1.5 = instrument-coverage smart prompting + badge cue; E2 = holdAutoplay gate. Tests: tests/js/tuner_auto_open.test.js (opt-in gate, persist mode, play/click-proofing). Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bc4d2a3592
commit
6bfd92aa06
@@ -26,7 +26,10 @@ function loadTuningHelpers() {
|
||||
|
||||
const feedBackHelpers = loadTuningHelpers();
|
||||
|
||||
function createTunerSandbox() {
|
||||
function createTunerSandbox(opts) {
|
||||
// Auto-open is opt-in (default off in prod). The sandbox defaults it ON so the
|
||||
// behaviour tests exercise the feature; pass { autoOpen: false } to gate it off.
|
||||
const autoOpen = !opts || opts.autoOpen !== false;
|
||||
const enableCalls = [];
|
||||
let playerActive = true;
|
||||
let songInfo = null;
|
||||
@@ -44,6 +47,7 @@ function createTunerSandbox() {
|
||||
showFloatingButton: true,
|
||||
visualizationMode: 'default',
|
||||
audioInputMode: 'auto',
|
||||
autoOpenOnTuningChange: autoOpen,
|
||||
lastInstrument: 'guitar-6',
|
||||
lastTuning: 'Standard',
|
||||
freeTune: false,
|
||||
@@ -155,9 +159,9 @@ function createTunerSandbox() {
|
||||
vm.runInContext(fs.readFileSync(TUNER_SCREEN_JS, 'utf8'), sandbox);
|
||||
|
||||
const realEnable = sandbox.window.tuner.enable.bind(sandbox.window.tuner);
|
||||
sandbox.window.tuner.enable = async () => {
|
||||
enableCalls.push(1);
|
||||
return realEnable();
|
||||
sandbox.window.tuner.enable = async (enableOpts) => {
|
||||
enableCalls.push(enableOpts || {});
|
||||
return realEnable(enableOpts);
|
||||
};
|
||||
|
||||
return sandbox;
|
||||
@@ -315,6 +319,37 @@ test('song:loading clears dismiss state for next load', async () => {
|
||||
assert.equal(sandbox.__enableCalls.length, 2);
|
||||
});
|
||||
|
||||
test('auto-open is gated off when the setting is disabled (opt-in)', async () => {
|
||||
const sandbox = createTunerSandbox({ autoOpen: false });
|
||||
sandbox.window._tunerAutoOpen.resetState();
|
||||
await ready(sandbox, CUSTOM_GUITAR);
|
||||
await ready(sandbox, E_STANDARD); // a real tuning change, but the setting is off
|
||||
assert.equal(sandbox.__enableCalls.length, 0);
|
||||
});
|
||||
|
||||
test('auto-open enables in persist mode (passes { auto: true })', async () => {
|
||||
const sandbox = createTunerSandbox();
|
||||
sandbox.window._tunerAutoOpen.resetState();
|
||||
await ready(sandbox, CUSTOM_GUITAR);
|
||||
await ready(sandbox, E_STANDARD);
|
||||
assert.equal(sandbox.__enableCalls.length, 1);
|
||||
assert.equal(sandbox.__enableCalls[0].auto, true);
|
||||
});
|
||||
|
||||
test('persist: an auto-opened tuner is not torn down by autoplay / stray clicks', () => {
|
||||
const screenSrc = fs.readFileSync(TUNER_SCREEN_JS, 'utf8');
|
||||
const uiSrc = fs.readFileSync(
|
||||
path.join(__dirname, '..', '..', 'plugins', 'tuner', 'utils', 'ui.js'), 'utf8');
|
||||
// The gate is opt-in on the server config flag.
|
||||
assert.match(screenSrc, /autoOpenOnTuningChange/);
|
||||
// enable() records whether this was an auto-open …
|
||||
assert.match(screenSrc, /_state\.autoOpened\s*=\s*auto/);
|
||||
// … the outside-click dismiss is armed only for a manual open …
|
||||
assert.match(screenSrc, /if \(!auto\)[\s\S]*?addEventListener\('click'/);
|
||||
// … and the autoplay song:play closer ignores an auto-opened tuner (the flash fix).
|
||||
assert.match(uiSrc, /state\.enabled && !state\.autoOpened/);
|
||||
});
|
||||
|
||||
test('screen.js registers song:loading and song:ready auto-open listeners at boot', () => {
|
||||
const src = fs.readFileSync(TUNER_SCREEN_JS, 'utf8');
|
||||
assert.match(src, /function _installAutoOpenListeners/);
|
||||
|
||||
Reference in New Issue
Block a user