From 37e751f1e33c179520cecb43ed64681ca55c5369 Mon Sep 17 00:00:00 2001 From: Adrian Sbardella Date: Tue, 3 Nov 2026 21:06:56 -0300 Subject: [PATCH 1/2] fix(fires): keep retained heat hidden when reenabling an empty filter Add a lifecycle regression and register it in the format scope. --- docs/CURRENT-STATE.md | 2 ++ scripts/format-scope.json | 1 + src/layers/firms/heatVisibility.test.mjs | 44 ++++++++++++++++++++++++ src/layers/firms/lifecycle.js | 3 +- 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/layers/firms/heatVisibility.test.mjs diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 66dd7068c..c67967183 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -2231,6 +2231,8 @@ view), so the weak fires the heatmap shows stay on screen as markers when it fades out; it reads each marker's already-built anchor instead of the ground floor cache, which only the close band warms. "N FIRES" cards from a 2° / 1° aggregation still label the hottest areas; their accent is the strongest fire's FRP color. +Re-enabling Active Fires keeps the retained heat imagery hidden when the current +filtered set is empty, including while a new snapshot is pending. The Active Fires row carries a "Fire intensity (FRP)" slider on a log scale whose track is painted with the ramp and ticked at the same six values (its diff --git a/scripts/format-scope.json b/scripts/format-scope.json index 3df4155f2..606314960 100644 --- a/scripts/format-scope.json +++ b/scripts/format-scope.json @@ -408,6 +408,7 @@ "src/layers/firms/cards.js", "src/layers/firms/index.js", "src/layers/firms/ingestion.js", + "src/layers/firms/heatVisibility.test.mjs", "src/layers/firms/lifecycle.js", "src/layers/firms/model.js", "src/layers/firms/policy.js", diff --git a/src/layers/firms/heatVisibility.test.mjs b/src/layers/firms/heatVisibility.test.mjs new file mode 100644 index 000000000..4926db156 --- /dev/null +++ b/src/layers/firms/heatVisibility.test.mjs @@ -0,0 +1,44 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { createLifecycle } from './lifecycle.js'; + +test('reenabling an empty filtered layer never reveals the retained pre-filter heat raster', async () => { + let shown = false; + const noop = () => {}; + const layerState = { + _enabled: false, + _viewer: {}, + _dataSource: {}, + _fires: [], + _loading: true, + _pickIndexById: new Map(), + _heatImagery: { + setShow(v) { + shown = v; + }, + }, + }; + const lifecycle = createLifecycle({ + layerState, + services: { + picking: { registerPickOwner: noop, unregisterPickOwner: noop }, + sprites: { restoreSpriteOrderOnEnable: noop }, + context: { clearSelectedEntityContextForLayer: noop }, + }, + config: { id: 'local-firms', overlayHost: { setVisible: noop } }, + components: { + rendering: { applyHandoffFade: noop }, + viewport: { installLodWatcher: noop, installMoveEndWatcher: noop }, + selection: { installClickHandler: noop }, + }, + }); + await lifecycle.methods.enable(layerState._viewer); + assert.equal( + shown, + false, + 'empty current set must keep the old raster hidden while refresh is pending', + ); + layerState._fires = [{ frp: null, confidence: null }]; + await lifecycle.methods.enable(layerState._viewer); + assert.equal(shown, true, 'nonempty sets still resume their raster'); +}); diff --git a/src/layers/firms/lifecycle.js b/src/layers/firms/lifecycle.js index 541efca16..90d9cc217 100644 --- a/src/layers/firms/lifecycle.js +++ b/src/layers/firms/lifecycle.js @@ -54,7 +54,8 @@ export function createLifecycle({ layerState._billboards.show = true; } overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, true); - layerState._heatImagery?.setShow(true); + // A filter can leave an old raster cached while the current set is empty. + layerState._heatImagery?.setShow(layerState._fires.length > 0); // The camera can have crossed the hand-off while the layer was off. components.rendering.applyHandoffFade(true); components.viewport.installLodWatcher(); From 19e85941e63fad99439e77739137666f686bff45 Mon Sep 17 00:00:00 2001 From: Adrian Sbardella Date: Tue, 3 Nov 2026 21:07:29 -0300 Subject: [PATCH 2/2] docs: add changelog entry for empty-filter heat lifecycle fix --- changelog.d/1535-fires-empty-heat-reenable.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.d/1535-fires-empty-heat-reenable.md diff --git a/changelog.d/1535-fires-empty-heat-reenable.md b/changelog.d/1535-fires-empty-heat-reenable.md new file mode 100644 index 000000000..a862a7b56 --- /dev/null +++ b/changelog.d/1535-fires-empty-heat-reenable.md @@ -0,0 +1,2 @@ +- Keep retained Active Fires heat imagery hidden when an empty filtered layer is + re-enabled while a new snapshot is pending (radianx, #1535).