Skip to content

Commit 3316269

Browse files
committed
improved map state reset
1 parent 5a04ca4 commit 3316269

4 files changed

Lines changed: 63 additions & 3 deletions

File tree

app/javascript/controllers/map_controller.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import { Controller } from '@hotwired/stimulus'
22
import * as functions from 'helpers/functions'
3-
import { initializeMap, setBackgroundMapLayer, initializeViewMode,
3+
import { initializeMap, setBackgroundMapLayer, initializeViewMode,
44
initializeStaticMode, addFeature } from 'maplibre/map'
55
import { initializeEditMode } from 'maplibre/edit'
66
import { initializeSocket, mapChannel } from 'channels/map_channel'
7-
import { addUndoState } from 'maplibre/undo'
7+
import { addUndoState, clearUndoHistory } from 'maplibre/undo'
8+
import { resetInitializationState } from 'maplibre/layers/layers'
9+
import { clearImageState } from 'maplibre/styles/styles'
810

911
export default class extends Controller {
1012
async connect () {
13+
// Clear module-level state from previous map
14+
resetInitializationState()
15+
clearImageState()
16+
clearUndoHistory()
17+
1118
functions.e('#map-header nav', e => { e.style.display = 'none' })
1219
await initializeMap('maplibre-map')
1320
// static mode is used for screenshots
@@ -20,6 +27,26 @@ export default class extends Controller {
2027
setBackgroundMapLayer()
2128
}
2229

30+
disconnect() {
31+
// Clean up when navigating away from the map
32+
console.log('Map controller disconnecting, cleaning up...')
33+
34+
// Remove the map instance
35+
if (window.map) {
36+
try {
37+
window.map.remove()
38+
window.map = null
39+
} catch (e) {
40+
console.warn('Error removing map instance:', e)
41+
}
42+
}
43+
44+
// Clear module-level state
45+
resetInitializationState()
46+
clearImageState()
47+
clearUndoHistory()
48+
}
49+
2350
// paste feature from clipboard
2451
async paste(_event) {
2552

app/javascript/maplibre/layers/layers.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ export let layers // Layer instances: GeoJSONLayer, OverpassLayer, WikipediaLaye
77
// Cached promise to ensure initializeLayers only runs once
88
let initializePromise = null
99

10+
/**
11+
* Resets the initialization state when navigating to a new map.
12+
* This allows layers to be re-initialized from scratch.
13+
*/
14+
export function resetInitializationState() {
15+
initializePromise = null
16+
layers = null
17+
}
18+
1019
/**
1120
* Loads layer definitions from server and initializes them.
1221
* Combines loadLayerDefinitions(), initializeLayerSources(), and initializeLayerStyles()

app/javascript/maplibre/styles/styles.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from 'maplibre/feature'
1111
import { getFeature } from 'maplibre/layers/layers'
1212
import { frontFeature, map, removeStyleLayers } from 'maplibre/map'
13+
import { defaultFont } from 'maplibre/styles/basemaps'
1314

1415
export const viewStyleNames = [
1516
'polygon-layer',
@@ -120,6 +121,12 @@ export function initializeClusterStyles(sourceName, icon) {
120121
// loading images from 'marker-image-url' attributes
121122
// avoid loading the same image by each web worker
122123
const imageState = {} // 'loading' | 'loaded' | 'error'
124+
125+
// Clear image state when navigating to a new map
126+
export function clearImageState() {
127+
Object.keys(imageState).forEach(key => delete imageState[key])
128+
}
129+
123130
export async function loadImage (e) {
124131
// Skip if already loading, loaded, or failed
125132
if (imageState[e.id]) {
@@ -319,7 +326,7 @@ const labelSize = [
319326
]
320327

321328
// default font is set in basemap def basemaps[backgroundMapLayer]['font']
322-
export let labelFont // array
329+
export let labelFont = [defaultFont] // array - initialize with default to prevent null errors
323330

324331
// Shared configuration for symbols layers
325332
function symbolsLayerStyles(mode) {

app/javascript/maplibre/undo.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ import { resetDirections } from 'maplibre/routing/osrm'
88
let undoStack = []
99
let redoStack = []
1010

11+
/**
12+
* Clears undo/redo history when navigating to a new map
13+
*/
14+
export function clearUndoHistory() {
15+
undoStack = []
16+
redoStack = []
17+
// Try to hide buttons if they exist
18+
try {
19+
const undoBtn = document.querySelector('button.maplibregl-ctrl-undo')
20+
const redoBtn = document.querySelector('button.maplibregl-ctrl-redo')
21+
if (undoBtn) undoBtn.classList.add('hidden')
22+
if (redoBtn) redoBtn.classList.add('hidden')
23+
} catch (_e) {
24+
// Buttons may not exist yet
25+
}
26+
}
27+
1128
export function addUndoState(type, state, clearRedo = true) {
1229
// Deep clone to avoid mutation
1330
undoStack.push({ type: type, state: JSON.parse(JSON.stringify(state)) })

0 commit comments

Comments
 (0)