mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Remove the Operator HUD layout
Display > HUD > Layout and the set_hud voice action now offer Tactical, Minimal and Cyber. The Operator option, its CSS and its QA coverage are removed, and the unused "Operator" translations are pruned. Share-link codes are append-only, so operator keeps its hudVariant code. A link, scene or saved state that names it restores the default Tactical layout. The voice schema pins keep their legacy digests by restoring the retired value before comparing; the full-payload digest is re-derived.
This commit is contained in:
1 parent
aaa3ff46cf
commit
8b2c699370
26 files changed
+78
-147
No files matched your search
@@ -1337,7 +1337,7 @@ export class StyleManager extends ShellFacade {
|
||||
|
||||
/**
|
||||
* Switches the HUD layout variant.
|
||||
* @param {'tactical'|'operator'|'minimal'|'cyber'} variantName - Layout variant.
|
||||
* @param {'tactical'|'minimal'|'cyber'} variantName - Layout variant.
|
||||
* @returns {{ok: boolean, layout?: string, visible?: boolean, error?: string}}
|
||||
*/
|
||||
setHudLayout(variantName) {
|
||||
|
||||
@@ -72,7 +72,7 @@ test('opening already-expanded Radio reveals Context and closes Display', () =>
|
||||
});
|
||||
|
||||
test('non-Cyber explicit panels and restored preferences retain their existing policy', () => {
|
||||
for (const theme of ['tactical', 'operator', 'minimal', 'cyber']) {
|
||||
for (const theme of ['tactical', 'minimal', 'cyber']) {
|
||||
const f = fixture(theme), prior = globalThis.document;
|
||||
globalThis.document = f.doc;
|
||||
try {
|
||||
|
||||
@@ -132,7 +132,7 @@ test('rejects the whole invalid request before any mutation', () => {
|
||||
});
|
||||
|
||||
test('requires Cyber and preserves off state and every omitted setting', () => {
|
||||
for (const theme of ['tactical', 'operator', 'minimal']) {
|
||||
for (const theme of ['tactical', 'minimal']) {
|
||||
const f = fixture(theme);
|
||||
assert.equal(setCyberSonarControls(f.owner, { enabled: true }, f.doc).ok, false);
|
||||
assert.deepEqual(f.calls, []);
|
||||
|
||||
+20
-17
@@ -54,7 +54,8 @@ function styleOwner(t, initialVariant = 'cyber') {
|
||||
const hud = {
|
||||
getVariant: () => variant,
|
||||
setVariant: (value) => {
|
||||
variant = value;
|
||||
// Normalize like the real HUD so retired layouts fall back.
|
||||
variant = normalizeHudLayout(value);
|
||||
applyHudUiTheme(root, value);
|
||||
},
|
||||
setMode: (value) => calls.push(['mode', value]),
|
||||
@@ -131,7 +132,7 @@ test('visual styles retain Cyber through real preset application without droppin
|
||||
|
||||
test('non-Cyber style presets and explicit HUD choices remain authoritative', (t) => {
|
||||
const { owner, hud, root } = styleOwner(t);
|
||||
for (const variant of ['tactical', 'operator', 'minimal']) {
|
||||
for (const variant of ['tactical', 'minimal']) {
|
||||
owner._setHudVariant(variant);
|
||||
assert.equal(hud.getVariant(), variant);
|
||||
assert.equal(root.dataset.uiTheme, undefined);
|
||||
@@ -150,8 +151,8 @@ test('leaving Cyber without a preset choice restores the prior visual preset', (
|
||||
assert.equal(owner._preCyberStyle, 'noir');
|
||||
assert.equal(owner._cyberStyleUserSelected, false);
|
||||
|
||||
owner._setHudVariant('operator', { applyVisualDefaults: true });
|
||||
assert.equal(hud.getVariant(), 'operator');
|
||||
owner._setHudVariant('minimal', { applyVisualDefaults: true });
|
||||
assert.equal(hud.getVariant(), 'minimal');
|
||||
assert.equal(owner.activeStyle, 'noir');
|
||||
assert.equal(owner._preCyberStyle, null);
|
||||
assert.equal(owner._cyberStyleUserSelected, false);
|
||||
@@ -170,8 +171,8 @@ test('a preset explicitly selected in Cyber survives exit and resets for re-entr
|
||||
// Reselecting the active mode must not erase the user's preset intent.
|
||||
owner._setHudVariant('cyber', { applyVisualDefaults: true });
|
||||
assert.equal(owner._preCyberStyle, 'noir');
|
||||
owner._setHudVariant('operator', { applyVisualDefaults: true });
|
||||
assert.equal(hud.getVariant(), 'operator');
|
||||
owner._setHudVariant('minimal', { applyVisualDefaults: true });
|
||||
assert.equal(hud.getVariant(), 'minimal');
|
||||
assert.equal(owner.activeStyle, 'snow');
|
||||
assert.equal(owner._preCyberStyle, null);
|
||||
assert.equal(owner._cyberStyleUserSelected, false);
|
||||
@@ -192,7 +193,7 @@ test('an explicit same-value FLIR choice is preserved on Cyber exit', (t) => {
|
||||
owner.setStyle('thermal', { userInitiated: true });
|
||||
assert.equal(owner.activeStyle, 'thermal');
|
||||
assert.equal(owner._cyberStyleUserSelected, true);
|
||||
owner._setHudVariant('operator', { applyVisualDefaults: true });
|
||||
owner._setHudVariant('minimal', { applyVisualDefaults: true });
|
||||
assert.equal(owner.activeStyle, 'thermal');
|
||||
});
|
||||
|
||||
@@ -207,7 +208,7 @@ test('an authoritative same-Cyber reset clears local preset ownership', (t) => {
|
||||
assert.equal(owner.activeStyle, 'snow');
|
||||
assert.equal(owner._preCyberStyle, null);
|
||||
assert.equal(owner._cyberStyleUserSelected, false);
|
||||
owner._setHudVariant('operator', { applyVisualDefaults: true });
|
||||
owner._setHudVariant('minimal', { applyVisualDefaults: true });
|
||||
assert.equal(owner.activeStyle, 'snow');
|
||||
});
|
||||
|
||||
@@ -241,9 +242,9 @@ test('Display and voice HUD routes preserve explicit Cyber entry and exit author
|
||||
assert.equal(display.owner.activeStyle, 'thermal');
|
||||
snowButton.dispatchEvent(new Event('click'));
|
||||
assert.equal(display.owner.activeStyle, 'snow');
|
||||
hudLayout.value = 'operator';
|
||||
hudLayout.value = 'minimal';
|
||||
hudLayout.dispatchEvent(new Event('change'));
|
||||
assert.equal(display.hud.getVariant(), 'operator');
|
||||
assert.equal(display.hud.getVariant(), 'minimal');
|
||||
assert.equal(display.owner.activeStyle, 'snow');
|
||||
controls.destroy();
|
||||
|
||||
@@ -266,9 +267,9 @@ test('Display and voice HUD routes preserve explicit Cyber entry and exit author
|
||||
const selected = await runVoiceAction('set_visual_style', { style: 'snow' });
|
||||
assert.equal(selected.ok, true);
|
||||
assert.equal(voice.owner.activeStyle, 'snow');
|
||||
const exited = await runVoiceAction('set_hud', { layout: 'operator' });
|
||||
const exited = await runVoiceAction('set_hud', { layout: 'minimal' });
|
||||
assert.equal(exited.ok, true);
|
||||
assert.equal(voice.hud.getVariant(), 'operator');
|
||||
assert.equal(voice.hud.getVariant(), 'minimal');
|
||||
assert.equal(voice.owner.activeStyle, 'snow');
|
||||
});
|
||||
|
||||
@@ -284,7 +285,7 @@ test('scope choice and expanded feather survive every HUD layout and both restor
|
||||
assert.equal(owner._scopeBtn.checked, false);
|
||||
assert.equal(owner._scopeFeatherSlider.disabled, true);
|
||||
assert.equal(owner._scopeFeatherSlider.value, '200');
|
||||
for (const layout of ['minimal', 'operator', 'cyber', 'tactical']) {
|
||||
for (const layout of ['minimal', 'cyber', 'tactical']) {
|
||||
owner._setHudVariant(layout, { applyVisualDefaults: true });
|
||||
assert.equal(isScopeMaskEnabled(), false, layout);
|
||||
assert.equal(getScopeMaskFeather(), 2, layout);
|
||||
@@ -313,7 +314,7 @@ test('scene and share HUD transitions do not restore a local pre-Cyber preset',
|
||||
assert.equal(owner.activeStyle, 'retro');
|
||||
assert.equal(owner._preCyberStyle, null);
|
||||
assert.equal(owner._cyberStyleUserSelected, false);
|
||||
owner._setHudVariant('operator', { applyVisualDefaults: true });
|
||||
owner._setHudVariant('minimal', { applyVisualDefaults: true });
|
||||
assert.equal(owner.activeStyle, 'retro');
|
||||
|
||||
owner.setStyle('surveillance');
|
||||
@@ -342,7 +343,8 @@ test('scene and share restoration override Cyber and preserve restored Cyber par
|
||||
style: 'surveillance',
|
||||
hudVariant: 'operator',
|
||||
});
|
||||
assert.equal(hud.getVariant(), 'operator');
|
||||
// A link saved with the retired Operator layout restores as Tactical.
|
||||
assert.equal(hud.getVariant(), 'tactical');
|
||||
await owner.restoreShareState({
|
||||
style: 'thermal',
|
||||
hudVariant: 'cyber',
|
||||
@@ -564,8 +566,9 @@ test('Cyber side panels share one width and one framed surface material', () =>
|
||||
});
|
||||
|
||||
test('Cyber is a canonical HUD layout with a safe Tactical fallback', () => {
|
||||
assert.deepEqual(HUD_LAYOUTS, ['tactical', 'operator', 'minimal', 'cyber']);
|
||||
assert.deepEqual(HUD_LAYOUTS, ['tactical', 'minimal', 'cyber']);
|
||||
assert.equal(normalizeHudLayout('CYBER'), 'cyber');
|
||||
assert.equal(normalizeHudLayout('operator'), 'tactical');
|
||||
assert.equal(normalizeHudLayout('unknown'), 'tactical');
|
||||
});
|
||||
|
||||
@@ -597,7 +600,7 @@ test('an explicit transition into Cyber selects FLIR with Ironbow 0.42 once', ()
|
||||
);
|
||||
assert.equal(cyberVisualDefaultsForHudTransition('tactical', 'cyber'), null);
|
||||
assert.equal(
|
||||
cyberVisualDefaultsForHudTransition('cyber', 'operator', {
|
||||
cyberVisualDefaultsForHudTransition('cyber', 'minimal', {
|
||||
explicit: true,
|
||||
}),
|
||||
null,
|
||||
|
||||
@@ -39,7 +39,7 @@ test('Cyber restores one expanded owner, keeps launchers, and restores other the
|
||||
true,
|
||||
'layout does not reopen a peer',
|
||||
);
|
||||
f.options.hud.variant = 'operator';
|
||||
f.options.hud.variant = 'minimal';
|
||||
f.run();
|
||||
assert.equal(f.first.classList.contains('collapsed'), false);
|
||||
assert.equal(
|
||||
|
||||
@@ -463,17 +463,10 @@ body:not(.ui-clean-view):not(.recording-mode):has(
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='tactical'] .hud-bottom-left,
|
||||
#intel-hud[data-variant='tactical'] .hud-bottom-right,
|
||||
#intel-hud[data-variant='operator'] .hud-bottom-left,
|
||||
#intel-hud[data-variant='operator'] .hud-bottom-right {
|
||||
#intel-hud[data-variant='tactical'] .hud-bottom-right {
|
||||
bottom: calc(2vh + 6.5rem);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-bottom-bar {
|
||||
bottom: calc(2vh + 9.8rem);
|
||||
width: min(48vw, 680px);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='minimal'] .hud-bottom-left {
|
||||
bottom: calc(2vh + 5.4rem);
|
||||
}
|
||||
|
||||
@@ -303,49 +303,11 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-top-bar,
|
||||
#intel-hud[data-variant='operator'] .hud-bottom-bar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-top-bar {
|
||||
top: max(10vh, 90px);
|
||||
left: 50%;
|
||||
right: auto;
|
||||
width: min(52vw, 720px);
|
||||
transform: translateX(-50%);
|
||||
border-color: rgba(255, 255, 255, 0.24);
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0.56), rgba(8, 26, 34, 0.5));
|
||||
box-shadow: 0 0 24px rgba(0, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='tactical'] .hud-top-left,
|
||||
#intel-hud[data-variant='tactical'] .hud-top-right,
|
||||
#intel-hud[data-variant='operator'] .hud-top-left,
|
||||
#intel-hud[data-variant='operator'] .hud-top-right {
|
||||
#intel-hud[data-variant='tactical'] .hud-top-right {
|
||||
top: max(14vh, 136px);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-bottom-bar {
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0.52),
|
||||
rgba(8, 22, 18, 0.52)
|
||||
);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-corner {
|
||||
padding: 8px 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
border-radius: 8px;
|
||||
background: rgba(0, 0, 0, 0.36);
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-bracket {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='minimal'] .hud-top-right,
|
||||
#intel-hud[data-variant='minimal'] .hud-bottom-right,
|
||||
#intel-hud[data-variant='minimal'] .hud-left-edge,
|
||||
@@ -378,11 +340,7 @@
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is(
|
||||
[data-variant='minimal'],
|
||||
[data-variant='operator'],
|
||||
[data-variant='tactical']
|
||||
)
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='tactical'])
|
||||
.hud-readout,
|
||||
:root[data-scope-mask='off']:not([data-ui-theme='cyber']) .scene-text-holdout {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
@@ -399,11 +357,7 @@
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is(
|
||||
[data-variant='minimal'],
|
||||
[data-variant='operator'],
|
||||
[data-variant='tactical']
|
||||
)
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='tactical'])
|
||||
.hud-readout {
|
||||
display: block;
|
||||
width: max-content;
|
||||
@@ -413,11 +367,7 @@
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is(
|
||||
[data-variant='minimal'],
|
||||
[data-variant='operator'],
|
||||
[data-variant='tactical']
|
||||
)
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='tactical'])
|
||||
:is(.hud-top-right, .hud-bottom-right)
|
||||
.hud-readout,
|
||||
:root[data-scope-mask='off']:not([data-ui-theme='cyber'])
|
||||
@@ -427,29 +377,26 @@
|
||||
}
|
||||
|
||||
/* Preserve glyph opacity without dimming the vertical backplates. */
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is([data-variant='operator'], [data-variant='tactical'])
|
||||
.hud-edge {
|
||||
:root[data-scope-mask='off'] #intel-hud[data-variant='tactical'] .hud-edge {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is([data-variant='operator'], [data-variant='tactical'])
|
||||
#intel-hud[data-variant='tactical']
|
||||
.hud-edge
|
||||
.hud-readout
|
||||
> * {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off'] #intel-hud[data-variant='operator'] .hud-corner,
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='operator'])
|
||||
#intel-hud[data-variant='minimal']
|
||||
:is(.hud-top-bar, .hud-bottom-bar) {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='operator'])
|
||||
#intel-hud[data-variant='minimal']
|
||||
:is(.hud-top-bar, .hud-bottom-bar) {
|
||||
width: fit-content;
|
||||
max-width: calc(100vw - 120px);
|
||||
@@ -457,7 +404,7 @@
|
||||
}
|
||||
|
||||
:root[data-scope-mask='off']
|
||||
#intel-hud:is([data-variant='minimal'], [data-variant='operator'])
|
||||
#intel-hud[data-variant='minimal']
|
||||
:is(.hud-top-bar, .hud-bottom-bar)
|
||||
.hud-readout {
|
||||
overflow: hidden;
|
||||
|
||||
@@ -110,13 +110,6 @@
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
#intel-hud[data-variant='operator'] .hud-top-bar {
|
||||
left: 12px;
|
||||
right: auto;
|
||||
width: calc(100vw - 24px);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.hud-bottom-bar {
|
||||
bottom: 90px;
|
||||
font-size: 9px;
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<span class="pp-slider-mini-label" data-i18n>Layout</span>
|
||||
<select id="hud-layout-select" class="pp-select gev-field gev-field--compact" aria-label="HUD layout" data-i18n-aria-label>
|
||||
<option value="tactical" data-i18n>Tactical</option>
|
||||
<option value="operator" data-i18n>Operator</option>
|
||||
<option value="minimal" data-i18n>Minimal</option>
|
||||
<option value="cyber" data-i18n>Cyber</option>
|
||||
</select>
|
||||
|
||||
Reference in new issue
Block a user