diff --git a/CHANGELOG.md b/CHANGELOG.md index 01ee4282..65f6b698 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Deleting an import will no longer result in negative points count for the user. - Updating stats. #2022 - Validate trip start date to be earlier than end date. #2057 +- Fog of war radius slider in map v2 settings is now being respected correctly. +- Applying changes in map v2 settings now works correctly. # [0.36.4] - 2025-12-26 diff --git a/app/javascript/controllers/maps/maplibre/layer_manager.js b/app/javascript/controllers/maps/maplibre/layer_manager.js index b31fd539..2968713e 100644 --- a/app/javascript/controllers/maps/maplibre/layer_manager.js +++ b/app/javascript/controllers/maps/maplibre/layer_manager.js @@ -270,7 +270,7 @@ export class LayerManager { // Always create fog layer for backward compatibility if (!this.layers.fogLayer) { this.layers.fogLayer = new FogLayer(this.map, { - clearRadius: 1000, + clearRadius: this.settings.fogOfWarRadius || 1000, visible: this.settings.fogEnabled || false }) this.layers.fogLayer.add(pointsGeoJSON) diff --git a/app/javascript/controllers/maps/maplibre/settings_manager.js b/app/javascript/controllers/maps/maplibre/settings_manager.js index 4a9aae05..5d6ab5ac 100644 --- a/app/javascript/controllers/maps/maplibre/settings_manager.js +++ b/app/javascript/controllers/maps/maplibre/settings_manager.js @@ -244,8 +244,8 @@ export class SettingsController { if (settings.fogOfWarRadius) { fogLayer.clearRadius = settings.fogOfWarRadius } - // Redraw fog layer - if (fogLayer.visible) { + // Redraw fog layer if it has data and is visible + if (fogLayer.visible && fogLayer.data) { await fogLayer.update(fogLayer.data) } } diff --git a/app/javascript/maps_maplibre/layers/fog_layer.js b/app/javascript/maps_maplibre/layers/fog_layer.js index 431226d6..1112a9b7 100644 --- a/app/javascript/maps_maplibre/layers/fog_layer.js +++ b/app/javascript/maps_maplibre/layers/fog_layer.js @@ -12,9 +12,11 @@ export class FogLayer { this.ctx = null this.clearRadius = options.clearRadius || 1000 // meters this.points = [] + this.data = null // Store original data for updates } add(data) { + this.data = data // Store for later updates this.points = data.features || [] this.createCanvas() if (this.visible) { @@ -24,6 +26,7 @@ export class FogLayer { } update(data) { + this.data = data // Store for later updates this.points = data.features || [] this.render() } @@ -78,6 +81,7 @@ export class FogLayer { // Clear circles around visited points this.ctx.globalCompositeOperation = 'destination-out' + this.ctx.fillStyle = 'rgba(0, 0, 0, 1)' // Fully opaque to completely clear fog this.points.forEach(feature => { const coords = feature.geometry.coordinates diff --git a/e2e/v2/map/layers/advanced.spec.js b/e2e/v2/map/layers/advanced.spec.js index 965164a4..aa17ab46 100644 --- a/e2e/v2/map/layers/advanced.spec.js +++ b/e2e/v2/map/layers/advanced.spec.js @@ -36,6 +36,81 @@ test.describe('Advanced Layers', () => { expect(await fogToggle.isChecked()).toBe(true) }) + + test('fog radius setting can be changed and applied', async ({ page }) => { + // Enable fog layer first + await page.click('button[title="Open map settings"]') + await page.waitForTimeout(400) + await page.click('button[data-tab="layers"]') + await page.waitForTimeout(300) + + const fogToggle = page.locator('label:has-text("Fog of War")').first().locator('input.toggle') + await fogToggle.check() + await page.waitForTimeout(500) + + // Go to advanced settings tab + await page.click('button[data-tab="settings"]') + await page.waitForTimeout(300) + + // Find fog radius slider + const fogRadiusSlider = page.locator('input[name="fogOfWarRadius"]') + await expect(fogRadiusSlider).toBeVisible() + + // Change the slider value using evaluate to trigger input event + await fogRadiusSlider.evaluate((slider) => { + slider.value = '500' + slider.dispatchEvent(new Event('input', { bubbles: true })) + }) + await page.waitForTimeout(200) + + // Verify display value updated + const displayValue = page.locator('[data-maps--maplibre-target="fogRadiusValue"]') + await expect(displayValue).toHaveText('500m') + + // Verify slider value was set + expect(await fogRadiusSlider.inputValue()).toBe('500') + + // Click Apply Settings button + const applyButton = page.locator('button:has-text("Apply Settings")') + await applyButton.click() + await page.waitForTimeout(500) + + // Verify no errors in console + const consoleErrors = [] + page.on('console', msg => { + if (msg.type() === 'error') consoleErrors.push(msg.text()) + }) + await page.waitForTimeout(500) + expect(consoleErrors.filter(e => e.includes('fog_layer'))).toHaveLength(0) + }) + + test('fog settings can be applied without errors when fog layer is not visible', async ({ page }) => { + await page.click('button[title="Open map settings"]') + await page.waitForTimeout(400) + await page.click('button[data-tab="settings"]') + await page.waitForTimeout(300) + + // Change fog radius slider without enabling fog layer + const fogRadiusSlider = page.locator('input[name="fogOfWarRadius"]') + await fogRadiusSlider.evaluate((slider) => { + slider.value = '750' + slider.dispatchEvent(new Event('input', { bubbles: true })) + }) + await page.waitForTimeout(200) + + // Click Apply Settings - this should not throw an error + const applyButton = page.locator('button:has-text("Apply Settings")') + await applyButton.click() + await page.waitForTimeout(500) + + // Verify no JavaScript errors occurred + const consoleErrors = [] + page.on('console', msg => { + if (msg.type() === 'error') consoleErrors.push(msg.text()) + }) + await page.waitForTimeout(500) + expect(consoleErrors.filter(e => e.includes('undefined') || e.includes('fog'))).toHaveLength(0) + }) }) test.describe('Scratch Map', () => {