diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f5c65a6..351b768d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -151,7 +151,9 @@ cloud-filter slider: 0% is Full, 100% is the existing brightness key, and intermediate values blend the keyed alpha. The slider commits on release to avoid restaging imagery for every drag event. Filter percentages round-trip in - share links; legacy mode codes retain their old endpoint meanings. + share links; legacy mode codes retain their old endpoint meanings. Background + panel refreshes preserve the pending drag value until release. Contributed by + [NotProniss](https://github.com/NotProniss) (#1084). - Flights and Military Flights highlight emergency transponder broadcasts in fleet billboards, 3D models and Cockpit contacts. Colors update when a status diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 629d1416f..09b065630 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -259,7 +259,9 @@ preserved in Full image mode; both modes use the chosen layer opacity. This is a display filter, not a cloud mask. The cloud-filter slider is a continuous 0–100% strength: 0% is Full, 100% is the existing Clouds only key, and intermediate values blend their alpha. The value commits on slider release to -avoid restaging for every pointer event. Satellite share links carry the filter +avoid restaging for every pointer event. Status refreshes retain the uncommitted +drag preview; changed model values or disabled controls supersede it. +Satellite share links carry the filter strength; legacy `f`/`a` values keep their Clouds only / Full meanings. Soft and Vivid remain layer-opacity presets (40%/70%); history remains transient and links open latest. diff --git a/src/ui/railCardBlocks.js b/src/ui/railCardBlocks.js index b58e1134f..1726860f9 100644 --- a/src/ui/railCardBlocks.js +++ b/src/ui/railCardBlocks.js @@ -110,6 +110,7 @@ export function createRailCardBlocks({ container, cardId, onParams }) { const value = Number(block.rangeInput.value); const params = rangeParams(); if (!params) return; + if (range.commitOnChange) block.rangeDraft = { range, value }; set( block.rangeValue, 'textContent', @@ -125,6 +126,7 @@ export function createRailCardBlocks({ container, cardId, onParams }) { const onChange = () => { if (!block.props.range?.commitOnChange) return; const params = rangeParams(); + block.rangeDraft = null; if (params) dispatch(params); }; block.rangeInput.addEventListener('input', onInput); @@ -196,11 +198,22 @@ export function createRailCardBlocks({ container, cardId, onParams }) { syncChipGroup(block.chips, props.chips); const range = props.range; set(block.rangeRow, 'hidden', !range); + const draft = block.rangeDraft; + if ( + draft && + (!range || + range.disabled || + !range.commitOnChange || + ['id', 'param', 'min', 'max', 'step', 'value'].some( + (key) => range[key] !== draft.range[key], + )) + ) + block.rangeDraft = null; if (range) { const min = Number(range.min); const max = Number(range.max); const step = Number(range.step); - const candidate = Number(range.value); + const candidate = Number(block.rangeDraft?.value ?? range.value); const value = Math.min( max, Math.max(min, Number.isFinite(candidate) ? candidate : min), diff --git a/src/ui/railCards.test.mjs b/src/ui/railCards.test.mjs index 48fe93964..74629bebb 100644 --- a/src/ui/railCards.test.mjs +++ b/src/ui/railCards.test.mjs @@ -183,11 +183,26 @@ test('setting ranges stay below presets and commit expensive filters on release' .textContent, '53%', ); + view.update([model(100)]); + assert.equal(slider.value, '53', 'a status refresh retains the pending drag'); + assert.equal( + slider.getAttribute('aria-valuetext'), + '53%', + 'the accessible preview also survives a refresh', + ); slider.dispatchEvent(new Event('change')); assert.deepEqual(calls.at(-1), ['a', { infrared: 53 }]); view.update([model(53)]); assert.equal(slider.value, '53'); assert.equal(f.document.activeElement, slider); + slider.value = '41'; + slider.dispatchEvent(new Event('input')); + view.update([model(70)]); + assert.equal( + slider.value, + '70', + 'an authoritative value supersedes the draft', + ); view.destroy(); slider.value = '41'; slider.dispatchEvent(new Event('change')); diff --git a/src/ui/styles/weather.css b/src/ui/styles/weather.css index 02ee75ea6..0540fac0a 100644 --- a/src/ui/styles/weather.css +++ b/src/ui/styles/weather.css @@ -351,7 +351,8 @@ body.recording-mode .gev-wind-inspection-marker { outline-offset: 3px; } .rail-card-setting-range-value { - min-width: 3ch; + flex: 0 0 4ch; + white-space: nowrap; color: var(--text-primary); font: 9px var(--font-mono); text-align: right;