mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat(ui): render the Space Missions roster and selected mission from the launches layer's published view
The launches layer no longer builds the roster or the selected mission panel as HTML strings in #space-mission-panel-host. It presents both as a plain view and publishes it through subscribePanel(); MissionRoster and MissionDetail render it from the gev-context store and call the layer's panel commands. Replay controls are presented the same way. The roster keeps keyboard focus on the same mission across refreshes, or continues beyond the list when the mission departs, and the row under the pointer takes the preview back on its next movement. Lines a null view rebuilds are translated through t(). Disposing the shell clears the Contacts and Space Missions views.
This commit is contained in:
1 parent
1e4df63efe
commit
66a60ff67e
23 files changed
+1131
-605
No files matched your search
@@ -3,7 +3,6 @@ import { GEV_REALTIME_TOOLS } from '../server/providers/openai/tools.js';
|
||||
import { realtimeInstructions } from '../server/providers/openai/instructions.js';
|
||||
import { readShellSource } from './testSupport/readShellSource.mjs';
|
||||
import { renderApplicationHtml } from './testSupport/applicationHtml.mjs';
|
||||
import { readLayerSource } from './testSupport/readLayerSource.mjs';
|
||||
import { readStylesheet } from './testSupport/readStylesheet.mjs';
|
||||
import { readFileSync as readRadioSource } from 'node:fs';
|
||||
const radioBindings = readRadioSource(new URL('./ui/radioBindings.js', import.meta.url), 'utf8');
|
||||
@@ -19,7 +18,7 @@ const ui = readShellSource();
|
||||
const radio = ['playback', 'interaction'].map(name =>
|
||||
readFileSync(new URL(`./layers/radio/${name}.js`, import.meta.url), 'utf8')
|
||||
).join('\n').replace(/layerState\.|parts\.\w+\./g, '');
|
||||
const rocketLaunches = readLayerSource(new URL('./data/rocketLaunches.js', import.meta.url), 'utf8');
|
||||
const missionDetail = readFileSync(new URL('./ui/views/panels/MissionDetail.vue', import.meta.url), 'utf8');
|
||||
const realtime = readRealtimeSource();
|
||||
const voice = ['./voice/actionSchemas.js', '../server/providers/openai/toolDescriptions.js', '../server/providers/openai/instructions.js'].map(file => readFileSync(new URL(file, import.meta.url), 'utf8')).join('\n');
|
||||
const css = readStylesheet(new URL('../style.css', import.meta.url));
|
||||
@@ -270,10 +269,10 @@ test('Radio volume and mission speed share the Sharpen slider visual language',
|
||||
);
|
||||
}
|
||||
assert.match(
|
||||
rocketLaunches,
|
||||
missionDetail,
|
||||
/id="space-mission-replay-speed" class="gev-quantitative-slider" type="range" min="0\.25" max="4" step="0\.25" value="1"/,
|
||||
);
|
||||
assert.match(rocketLaunches, /class="gev-slider-value"[^>]*data-mission-replay-speed-output/);
|
||||
assert.match(missionDetail, /class="gev-slider-value"[^>]*data-mission-replay-speed-output/);
|
||||
assert.match(css, /\.gev-quantitative-slider\s*\{[\s\S]*?min-width: 0;[\s\S]*?height: 18px;/);
|
||||
assert.match(css, /\.gev-quantitative-slider::-webkit-slider-runnable-track\s*\{[\s\S]*?height: 3px;[\s\S]*?background: rgba\(255, 255, 255, 0\.08\);/);
|
||||
assert.match(css, /\.gev-quantitative-slider::-webkit-slider-thumb\s*\{[\s\S]*?width: 10px;[\s\S]*?height: 10px;[\s\S]*?border-radius: 50%;[\s\S]*?background: var\(--accent\);/);
|
||||
@@ -286,12 +285,8 @@ test('Radio volume and mission speed share the Sharpen slider visual language',
|
||||
test('Radio is nested inside Context with its own disclosure and power controls', () => {
|
||||
const contextStart = html.indexOf('id="global-context-panel"');
|
||||
const radioStart = html.indexOf('id="radio-panel"');
|
||||
// The Context panel ends with the right rail's own closing tag, after the
|
||||
// military awareness aside nested inside it.
|
||||
const contextEnd = html.indexOf(
|
||||
'</aside>',
|
||||
html.indexOf('</aside>', html.indexOf('id="military-awareness-panel"')) + 1,
|
||||
);
|
||||
// The Context view ends with the right rail, before the scene runtime.
|
||||
const contextEnd = html.indexOf('id="scene-runtime"');
|
||||
assert.ok(contextStart >= 0 && radioStart > contextStart && radioStart < contextEnd);
|
||||
assert.match(html, /id="radio-panel"[^>]*data-panel-id="radio-panel"/);
|
||||
assert.match(html, /aria-label="Radio playback"/);
|
||||
|
||||
Reference in new issue
Block a user