mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
refactor: isolate Radio controls and tuner presentation
This commit is contained in:
1 parent
79a0f09087
commit
7b9aca8597
21 files changed
+1507
-1134
No files matched your search
+30
-30
@@ -1,3 +1,7 @@
|
||||
import { readFileSync as readRadioSource } from 'node:fs';
|
||||
const radioBindings = readRadioSource(new URL('./ui/radioBindings.js', import.meta.url), 'utf8');
|
||||
const radioPresentation = readRadioSource(new URL('./ui/radioPresentation.js', import.meta.url), 'utf8');
|
||||
const radioControlsSource = readRadioSource(new URL('./ui/radioControls.js', import.meta.url), 'utf8');
|
||||
import assert from 'node:assert/strict';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { readFileSync } from 'node:fs';
|
||||
@@ -249,19 +253,19 @@ test('Radio is nested inside Context with separate disclosure and power controls
|
||||
assert.match(css, /--radio-broadcast-opacity: \.17/);
|
||||
assert.match(css, /@media \(prefers-reduced-motion: reduce\)[\s\S]*?\.radio-tuner-needle,[\s\S]*?\.radio-tuner-tick\s*\{\s*transition: none;/);
|
||||
assert.doesNotMatch(ui, /_radioTunerCameraRemove = this\.viewer\?\.camera\?\.changed/);
|
||||
assert.match(ui, /classList\.toggle\('radio-broadcasting', state\.audioState === 'playing'\)/);
|
||||
assert.match(ui, /cycleStation\(direction, \{[\s\S]*?rotate,[\s\S]*?stationIds:/);
|
||||
const cycleStart = ui.indexOf('const cycleRadio = (direction, { rotate = true } = {}) =>');
|
||||
const cycleMethod = ui.slice(cycleStart, ui.indexOf('const toggleRadio', cycleStart));
|
||||
assert.match(radioPresentation, /classList\.toggle\('radio-broadcasting', state\.audioState === 'playing'\)/);
|
||||
assert.match(radioBindings, /cycleStation\(direction, \{[\s\S]*?rotate,[\s\S]*?stationIds:/);
|
||||
const cycleStart = radioBindings.indexOf('const cycleRadio = (direction, { rotate = true } = {}) =>');
|
||||
const cycleMethod = radioBindings.slice(cycleStart, radioBindings.indexOf('const toggleRadio', cycleStart));
|
||||
assert.doesNotMatch(cycleMethod, /refreshTunerBand/);
|
||||
assert.match(ui, /_radioTunerBandPinnedForNavigation = true/);
|
||||
assert.match(ui, /viewer\?\.canvas\?\.addEventListener\('pointerdown', releaseNavigationBand/);
|
||||
assert.match(ui, /previewTuningStation\(station\?\.id \|\| null, \{ rotate \}\)/);
|
||||
assert.match(ui, /tunerPreview\(\{ coordinate: this\._radioTunerCoordinate, rotate: commit \}\)/);
|
||||
assert.match(ui, /radioLayer\.cancelTuning\(\)/);
|
||||
assert.match(ui, /classList\.remove\('radio-broadcasting'\)/);
|
||||
assert.match(ui, /radioLayer\.getTunerStations\(750\)/);
|
||||
assert.match(ui, /radioTunerPointerPosition\(/);
|
||||
assert.match(radioBindings, /_radioTunerBandPinnedForNavigation = true/);
|
||||
assert.match(radioBindings, /listen\(this\.canvas, 'pointerdown', releaseNavigationBand/);
|
||||
assert.match(radioBindings, /previewTuningStation\(station\?\.id \|\| null, \{ rotate \}\)/);
|
||||
assert.match(radioBindings, /tunerPreview\(\{ coordinate: this\._radioTunerCoordinate, rotate: commit \}\)/);
|
||||
assert.match(radioBindings, /this\.radio\.cancelTuning\(\)/);
|
||||
assert.match(radioControlsSource, /classList\.remove\('radio-broadcasting'\)/);
|
||||
assert.match(radioBindings, /this\.radio\.getTunerStations\(750\)/);
|
||||
assert.match(radioBindings, /radioTunerPointerPosition\(/);
|
||||
assert.doesNotMatch(css, /#right-context-rail\s*>\s*#radio-panel/);
|
||||
assert.match(css, /#global-context-panel #radio-panel\.collapsed/);
|
||||
assert.doesNotMatch(css, /\.context-radio-dock\.active:hover \.context-radio-mini/);
|
||||
@@ -277,16 +281,15 @@ test('panel collapse is presentation-only and Radio exposes explicit voice playb
|
||||
assert.match(voice, /'radio'/);
|
||||
assert.match(voice, /name:\s*'control_radio'/);
|
||||
assert.deepEqual(realtimeTools().find(tool => tool.name === 'control_radio').parameters.properties.action.enum, ['enable', 'disable', 'play', 'resume', 'pause', 'stop', 'next', 'previous', 'volume', 'select', 'status']);
|
||||
const enableStart = ui.lastIndexOf('\n _initRadioPanel()');
|
||||
const enableMethod = ui.slice(enableStart, ui.indexOf('\n _renderRadioState(state)', enableStart));
|
||||
const enableMethod = radioBindings;
|
||||
assert.doesNotMatch(enableMethod, /playSelectedRadio|togglePlayback\(\).*radio-enable/i);
|
||||
assert.match(enableMethod, /contextRadioToggleBtn/);
|
||||
assert.match(enableMethod, /contextRadioMiniEnableBtn/);
|
||||
assert.match(enableMethod, /contextRadioDetailsBtn/);
|
||||
assert.match(enableMethod, /contextRadioMiniCloseBtn/);
|
||||
assert.match(enableMethod, /contextRadioMiniPlayBtn/);
|
||||
const disclosureStart = enableMethod.indexOf('this._contextRadioToggleBtn?.addEventListener');
|
||||
const disclosureEnd = enableMethod.indexOf("this._radioFilter?.addEventListener", disclosureStart);
|
||||
const disclosureStart = enableMethod.indexOf('this.listen(this._contextRadioToggleBtn,');
|
||||
const disclosureEnd = enableMethod.indexOf("this.listen(this._radioFilter,", disclosureStart);
|
||||
const disclosureBindings = enableMethod.slice(disclosureStart, disclosureEnd);
|
||||
assert.ok(disclosureStart >= 0 && disclosureEnd > disclosureStart, 'compact Radio disclosure bindings are missing');
|
||||
assert.doesNotMatch(disclosureBindings, /toggleRadio\(this\._contextRadioToggleBtn\)/);
|
||||
@@ -304,32 +307,29 @@ test('panel collapse is presentation-only and Radio exposes explicit voice playb
|
||||
});
|
||||
|
||||
test('expanded Context routes its Radio icon to the embedded section and keeps collapsed Context compact', () => {
|
||||
const revealStart = ui.indexOf('\n async _revealRadioPanelInsideContext');
|
||||
const revealEnd = ui.indexOf('\n /**', revealStart + 10);
|
||||
const revealMethod = ui.slice(revealStart, revealEnd);
|
||||
const revealStart = radioControlsSource.indexOf('\n async _revealRadioPanelInsideContext');
|
||||
const revealEnd = radioControlsSource.indexOf('\n /**', revealStart + 10);
|
||||
const revealMethod = radioControlsSource.slice(revealStart, revealEnd);
|
||||
assert.ok(revealStart >= 0 && revealEnd > revealStart, 'embedded Radio reveal helper is missing');
|
||||
assert.match(revealMethod, /requestAnimationFrame\(\(\) => requestAnimationFrame/);
|
||||
assert.match(revealMethod, /scroller\.scrollTo\(\{ top: next, behavior: reducedMotion \? 'auto' : 'smooth' \}\)/);
|
||||
assert.match(revealMethod, /focus\?\.\(\{ preventScroll: true \}\)/);
|
||||
assert.doesNotMatch(revealMethod, /setEnabled|togglePlayback|selectStation|setContextMode/);
|
||||
|
||||
const syncStart = ui.indexOf('\n _syncContextRadioLauncherState()');
|
||||
const syncEnd = ui.indexOf('\n /**', syncStart + 10);
|
||||
const syncMethod = ui.slice(syncStart, syncEnd);
|
||||
const syncStart = radioControlsSource.indexOf('\n _syncContextRadioLauncherState()');
|
||||
const syncEnd = radioControlsSource.indexOf('\n destroy()', syncStart + 10);
|
||||
const syncMethod = radioControlsSource.slice(syncStart, syncEnd);
|
||||
assert.ok(syncStart >= 0 && syncEnd > syncStart, 'Context Radio launcher state sync is missing');
|
||||
assert.match(syncMethod, /contextExpanded[\s\S]*?aria-controls', 'radio-panel'[\s\S]*?aria-expanded', String\(radioExpanded\)/);
|
||||
assert.match(syncMethod, /aria-controls', 'context-radio-mini'[\s\S]*?aria-expanded', String\(compactOpen\)/);
|
||||
const renderStart = ui.indexOf('\n _renderRadioState(state)');
|
||||
const renderMethod = ui.slice(renderStart, ui.indexOf('\n _renderRadioTuner', renderStart));
|
||||
const renderMethod = radioPresentation;
|
||||
assert.match(renderMethod, /this\._syncContextRadioLauncherState\(\)/);
|
||||
assert.doesNotMatch(renderMethod, /compact Radio controls/);
|
||||
assert.doesNotMatch(renderMethod, /_contextRadioToggleBtn\.setAttribute\('aria-(?:controls|expanded|label)'/);
|
||||
});
|
||||
|
||||
test('Radio disclosure is explicit, starts closed while off, and preserves playback state', () => {
|
||||
const renderStart = ui.indexOf('\n _renderRadioState(state)');
|
||||
const renderMethod = ui.slice(renderStart, ui.indexOf('\n _renderRadioTuner', renderStart));
|
||||
assert.ok(renderStart >= 0, 'Radio render method is missing');
|
||||
const renderMethod = radioPresentation;
|
||||
assert.doesNotMatch(renderMethod, /setPanelCollapsed\('radio-panel', true\).*stopPlayback/s);
|
||||
assert.doesNotMatch(renderMethod, /_radioMiniExpanded\s*=\s*false.*audioState === 'playing'/s);
|
||||
assert.match(ui, /contextRadioDetailsBtn/);
|
||||
@@ -346,8 +346,8 @@ test('successful explicit user playback hands the speaker from voice to Radio',
|
||||
assert.ok(confirmedPlaying >= 0 && takeoverSignal > confirmedPlaying);
|
||||
assert.match(radio, /startPlayback: \(\) => playSelectedRadio\(\{ origin: 'voice', attemptId: options\.attemptId \}\)/);
|
||||
assert.match(radio, /selectRadioStation\(stationId, \{ autoplay: true, origin: 'user' \}\)/);
|
||||
assert.match(ui, /togglePlayback\(\{ origin: 'user' \}\)/);
|
||||
assert.match(ui, /cycleStation\(direction, \{[\s\S]*?origin: 'user'/);
|
||||
assert.match(ui, /commitTuningStation\(station\.id, \{ origin: 'user' \}\)/);
|
||||
assert.match(radioBindings, /togglePlayback\(\{ origin: 'user' \}\)/);
|
||||
assert.match(radioBindings, /cycleStation\(direction, \{[\s\S]*?origin: 'user'/);
|
||||
assert.match(radioBindings, /commitTuningStation\(station\.id, \{ origin: 'user' \}\)/);
|
||||
assert.match(realtime, /event\.origin === 'user' && event\.action === 'play' && this\.isActive\(\)[\s\S]*?this\.stop\(\{ preserveRadioPlayback: true \}\)/);
|
||||
});
|
||||
Reference in new issue
Block a user