diff --git a/assets/js/features/trail_manager.ts b/assets/js/features/trail_manager.ts index 10b6dcb..9070a54 100644 --- a/assets/js/features/trail_manager.ts +++ b/assets/js/features/trail_manager.ts @@ -60,6 +60,7 @@ export class TrailManager { private onTrailHoverEnd?: () => void; private trailHoverDebounceTimer?: ReturnType; private lastHoveredPath?: string; + private isDestroyed: boolean = false; constructor( trailLayer: LayerGroup, @@ -227,6 +228,7 @@ export class TrailManager { private flushPendingTrailUpdates() { this.trailUpdateRafId = null; + if (this.isDestroyed) return; for (const [callsign, isHistorical] of this.pendingTrailUpdates) { const trailState = this.trails.get(callsign); if (trailState) { @@ -482,7 +484,7 @@ export class TrailManager { if (path !== this.lastHoveredPath) { this.lastHoveredPath = path; this.trailHoverDebounceTimer = setTimeout(() => { - hoverCb(mouseLat, mouseLng, path); + if (!this.isDestroyed) hoverCb(mouseLat, mouseLng, path); }, 50); } }); @@ -557,10 +559,15 @@ export class TrailManager { } destroy() { + this.isDestroyed = true; if (this.trailUpdateRafId !== null) { cancelAnimationFrame(this.trailUpdateRafId); this.trailUpdateRafId = null; } + if (this.trailHoverDebounceTimer) { + clearTimeout(this.trailHoverDebounceTimer); + this.trailHoverDebounceTimer = undefined; + } this.pendingTrailUpdates.clear(); } diff --git a/assets/js/map.ts b/assets/js/map.ts index ebdec4f..e7ac99d 100644 --- a/assets/js/map.ts +++ b/assets/js/map.ts @@ -142,31 +142,6 @@ let MapAPRSMap = { initialZoom = 5; } - // Only use localStorage if no URL params are present - // Temporarily disabled - using server-side geolocation instead - /* - if (!useUrlParams) { - try { - const saved = localStorage.getItem("aprs_map_state"); - if (saved) { - const { lat, lng, zoom } = JSON.parse(saved); - if ( - typeof lat === "number" && - typeof lng === "number" && - typeof zoom === "number" && - self.isValidCoordinate(lat, lng) && - zoom >= 1 && - zoom <= 20 - ) { - initialCenter = { lat, lng }; - initialZoom = zoom; - } - } - } catch (e) { - } - } - */ - self.initializeMap(initialCenter, initialZoom); }, @@ -841,9 +816,9 @@ let MapAPRSMap = { } // Check if clicked element or its parent is a LiveView navigation link - const navLink = target.closest(".aprs-lv-link") as HTMLAnchorElement; + const navLink = target.closest(".aprs-lv-link"); - if (navLink && navLink.href) { + if (navLink instanceof HTMLAnchorElement && navLink.href) { e.preventDefault(); e.stopPropagation(); diff --git a/lib/aprsme/regex_cache.ex b/lib/aprsme/regex_cache.ex index 69d563b..a36a0e0 100644 --- a/lib/aprsme/regex_cache.ex +++ b/lib/aprsme/regex_cache.ex @@ -18,7 +18,7 @@ defmodule Aprsme.RegexCache do @impl true def init(_) do # Create ETS table for caching compiled regexes - :ets.new(@table_name, [:set, :public, :named_table, read_concurrency: true]) + :ets.new(@table_name, [:set, :protected, :named_table, read_concurrency: true]) {:ok, %{}} end diff --git a/lib/aprsme_web/channels/mobile_channel.ex b/lib/aprsme_web/channels/mobile_channel.ex index 5d4121e..b360ad5 100644 --- a/lib/aprsme_web/channels/mobile_channel.ex +++ b/lib/aprsme_web/channels/mobile_channel.ex @@ -302,11 +302,11 @@ defmodule AprsmeWeb.MobileChannel do defp ensure_float(value) when is_binary(value) do case Float.parse(String.trim(value)) do {float, ""} -> float - _ -> value + _ -> nil end end - defp ensure_float(value), do: value + defp ensure_float(_value), do: nil defp ensure_integer(value, _default) when is_integer(value), do: value