diff --git a/assets/css/app.css b/assets/css/app.css index ca5aab7..07e2872 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -4,20 +4,48 @@ /* This file is for your main application CSS */ +/* Ensure full height layout for map pages */ +html, +body { + height: 100%; + margin: 0; + padding: 0; +} + +/* Main content container for map pages */ +main { + height: 100vh; + overflow: hidden; +} + #map { height: calc(100vh - 60px); /* Adjust based on header height */ width: 100%; } -/* Full page map for APRS home page */ +/* Full page map for APRS home page and callsign pages */ #aprs-map { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; + position: fixed !important; + top: 0 !important; + left: 0 !important; + right: 0 !important; + bottom: 0 !important; + height: 100vh !important; + width: 100vw !important; + z-index: 1 !important; +} + +/* Ensure the map container div has proper dimensions */ +.phx-main { + position: relative; height: 100vh; - width: 100%; + overflow: hidden; +} + +/* Fix for LiveView containers */ +div[data-phx-main="true"] { + height: 100vh; + overflow: hidden; } /* Hide header on home page */ diff --git a/assets/js/app.js b/assets/js/app.js index 4c041ec..3948c69 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -27,149 +27,9 @@ let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute(" // Import minimal APRS map hook import MinimalAPRSMap from "./minimal_map.js"; -// Debug Map Hook -let DebugMap = { - mounted() { - console.log("DebugMap hook mounted"); - window.liveSocket.pushEvent("debug_info", { hook_mounted: true }); - - // Check if Leaflet is available - if (typeof L === "undefined") { - console.error("Leaflet library not loaded!"); - window.liveSocket.pushEvent("debug_info", { - leaflet_loaded: false, - errors: ["Leaflet not loaded"], - }); - return; - } - - window.liveSocket.pushEvent("debug_info", { leaflet_loaded: true }); - - // Get initial center and zoom from server-provided data attributes - let initialCenter, initialZoom; - try { - initialCenter = JSON.parse(this.el.dataset.center); - initialZoom = parseInt(this.el.dataset.zoom); - console.log("Parsed data - center:", initialCenter, "zoom:", initialZoom); - } catch (error) { - console.error("Error parsing map data attributes:", error); - window.liveSocket.pushEvent("debug_info", { - errors: ["Error parsing map data: " + error.message], - }); - // Fallback values - initialCenter = { lat: 39.8283, lng: -98.5795 }; - initialZoom = 5; - } - - // Check element dimensions - const rect = this.el.getBoundingClientRect(); - console.log("Map element dimensions:", rect); - - // Initialize basic map - try { - this.map = L.map(this.el, { - zoomControl: true, - attributionControl: true, - closePopupOnClick: true, - }).setView([initialCenter.lat, initialCenter.lng], initialZoom); - - console.log("Map initialized successfully"); - window.liveSocket.pushEvent("debug_info", { map_initialized: true }); - window.debugMapInstance = this.map; - } catch (error) { - console.error("Error initializing map:", error); - window.liveSocket.pushEvent("debug_info", { - map_initialized: false, - errors: ["Map init error: " + error.message], - }); - return; - } - - // Add OpenStreetMap tile layer - try { - const tileLayer = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { - attribution: - '© OpenStreetMap contributors | APRS.me', - maxZoom: 19, - }); - tileLayer.addTo(this.map); - console.log("Tile layer added successfully"); - - // Listen for tile layer events - tileLayer.on("loading", () => console.log("Tiles loading...")); - tileLayer.on("load", () => console.log("Tiles loaded")); - tileLayer.on("tileerror", (e) => console.error("Tile error:", e)); - } catch (error) { - console.error("Error adding tile layer:", error); - window.liveSocket.pushEvent("debug_info", { - errors: ["Tile layer error: " + error.message], - }); - } - - // Force initial size calculation - try { - this.map.invalidateSize(); - console.log("Map size invalidated"); - } catch (error) { - console.error("Error invalidating map size:", error); - } - - // Track when map is ready - this.map.whenReady(() => { - console.log("Debug map is ready"); - console.log("Map container size:", this.map.getSize()); - console.log("Map zoom:", this.map.getZoom()); - console.log("Map center:", this.map.getCenter()); - - try { - this.pushEvent("map_ready", {}); - } catch (error) { - console.error("Error in map ready callback:", error); - } - }); - - // Handle resize - window.addEventListener("resize", () => { - console.log("Window resized, invalidating map size"); - try { - this.map.invalidateSize(); - } catch (error) { - console.error("Error invalidating map size on resize:", error); - } - }); - - // Add a delayed size check - setTimeout(() => { - console.log("Delayed map size check"); - const rect = this.el.getBoundingClientRect(); - console.log("Map element dimensions after delay:", rect); - if (this.map) { - try { - this.map.invalidateSize(); - console.log("Map size re-invalidated after delay"); - } catch (error) { - console.error("Error re-invalidating map size:", error); - } - } - }, 1000); - }, - - destroyed() { - console.log("DebugMap hook destroyed"); - if (this.map) { - this.map.remove(); - this.map = null; - } - if (window.debugMapInstance) { - window.debugMapInstance = null; - } - }, -}; - // APRS Map Hook let Hooks = {}; Hooks.APRSMap = MinimalAPRSMap; -Hooks.DebugMap = DebugMap; let liveSocket = new LiveSocket("/live", Socket, { longPollFallbackMs: 2500, diff --git a/assets/js/minimal_map.js b/assets/js/minimal_map.js index 68e69c9..dd372c0 100644 --- a/assets/js/minimal_map.js +++ b/assets/js/minimal_map.js @@ -265,15 +265,68 @@ let MinimalAPRSMap = { // Zoom to location this.handleEvent("zoom_to_location", (data) => { + console.log("Zoom to location event received:", data); + + if (!this.map) { + console.error("Map not initialized, cannot zoom"); + return; + } + if (data.lat && data.lng) { const lat = parseFloat(data.lat); const lng = parseFloat(data.lng); const zoom = parseInt(data.zoom || 12); - this.map.setView([lat, lng], zoom, { - animate: true, - duration: 1, - }); + // Validate coordinates + if (isNaN(lat) || isNaN(lng) || lat < -90 || lat > 90 || lng < -180 || lng > 180) { + console.error("Invalid coordinates for zoom:", lat, lng); + return; + } + + if (isNaN(zoom) || zoom < 1 || zoom > 20) { + console.error("Invalid zoom level:", zoom); + return; + } + + console.log("Zooming map to:", lat, lng, "at zoom level:", zoom); + + try { + // Check element dimensions before zoom + const beforeRect = this.el.getBoundingClientRect(); + console.log("Element dimensions before zoom:", beforeRect); + + // Force map size recalculation before zoom + this.map.invalidateSize(); + + // Use a slight delay to ensure map is ready + setTimeout(() => { + if (this.map) { + this.map.setView([lat, lng], zoom, { + animate: true, + duration: 1, + }); + console.log("Zoom completed successfully"); + + // Check element dimensions after zoom + setTimeout(() => { + const afterRect = this.el.getBoundingClientRect(); + console.log("Element dimensions after zoom:", afterRect); + + if (afterRect.width === 0 || afterRect.height === 0) { + console.error("Map element lost dimensions after zoom!"); + // Try to restore dimensions + this.el.style.width = "100vw"; + this.el.style.height = "100vh"; + this.map.invalidateSize(); + } + }, 1000); + } + }, 100); + } catch (error) { + console.error("Error during zoom operation:", error); + } + } else { + console.warn("Missing lat/lng data for zoom operation:", data); } }); diff --git a/lib/aprs_web/controllers/page_controller.ex b/lib/aprs_web/controllers/page_controller.ex index 968899c..15f76ca 100644 --- a/lib/aprs_web/controllers/page_controller.ex +++ b/lib/aprs_web/controllers/page_controller.ex @@ -86,84 +86,6 @@ defmodule AprsWeb.PageController do }) end - def test_map(conn, _params) do - # Simple HTML test page for basic map functionality - html(conn, """ - - - - - - Map Test - APRS.me - - - - -
- Map Test
- Status: Initializing...
-
- ← Back to Main Map -
-
- - - - - - """) - end - defp format_uptime(seconds) when seconds <= 0, do: "Not connected" defp format_uptime(seconds) do diff --git a/lib/aprs_web/live/map_live/callsign_view.ex b/lib/aprs_web/live/map_live/callsign_view.ex index 7867bd6..cb31ebe 100644 --- a/lib/aprs_web/live/map_live/callsign_view.ex +++ b/lib/aprs_web/live/map_live/callsign_view.ex @@ -69,8 +69,8 @@ defmodule AprsWeb.MapLive.CallsignView do # Schedule regular cleanup of old packets from the map Process.send_after(self(), :cleanup_old_packets, 60_000) - # Auto-start replay after a short delay - Process.send_after(self(), :auto_start_replay, 2000) + # Auto-start replay after a short delay - TEMPORARILY DISABLED FOR DEBUGGING + # Process.send_after(self(), :auto_start_replay, 2000) {:ok, socket} else @@ -146,29 +146,32 @@ defmodule AprsWeb.MapLive.CallsignView do IO.puts("CallsignView: Map ready event received") socket = assign(socket, map_ready: true) - # Auto-start replay if it hasn't been started yet + # Auto-start replay if it hasn't been started yet - TEMPORARILY DISABLED FOR DEBUGGING socket = if socket.assigns.replay_started do IO.puts("CallsignView: Replay already started") socket else - IO.puts("CallsignView: Starting historical replay") - socket = start_historical_replay(socket) - assign(socket, replay_started: true, replay_active: true) + IO.puts("CallsignView: Skipping replay start for debugging") + # socket = start_historical_replay(socket) + # assign(socket, replay_started: true, replay_active: true) + socket end - # If we have a pending geolocation, zoom to it now + # If we have a pending geolocation, zoom to it after a delay socket = if socket.assigns.pending_geolocation do location = socket.assigns.pending_geolocation - IO.puts("CallsignView: Zooming to pending geolocation: #{inspect(location)}") - push_event(socket, "zoom_to_location", %{lat: location.lat, lng: location.lng, zoom: 12}) + IO.puts("CallsignView: Scheduling zoom to pending geolocation: #{inspect(location)}") + Process.send_after(self(), {:zoom_to_location, location.lat, location.lng, 12}, 1500) + socket else - # If we have a last known position, zoom to it + # If we have a last known position, zoom to it after a delay if socket.assigns.last_known_position do pos = socket.assigns.last_known_position - IO.puts("CallsignView: Zooming to last known position: #{inspect(pos)}") - push_event(socket, "zoom_to_location", %{lat: pos.lat, lng: pos.lng, zoom: 12}) + IO.puts("CallsignView: Scheduling zoom to last known position: #{inspect(pos)}") + Process.send_after(self(), {:zoom_to_location, pos.lat, pos.lng, 12}, 1500) + socket else IO.puts("CallsignView: No position data to zoom to") socket @@ -202,6 +205,12 @@ defmodule AprsWeb.MapLive.CallsignView do end end + def handle_info({:zoom_to_location, lat, lng, zoom}, socket) do + IO.puts("CallsignView: Executing delayed zoom to #{lat}, #{lng} at zoom #{zoom}") + socket = push_event(socket, "zoom_to_location", %{lat: lat, lng: lng, zoom: zoom}) + {:noreply, socket} + end + def handle_info(msg, socket) do case msg do {:delayed_zoom, %{lat: lat, lng: lng}} -> @@ -379,14 +388,18 @@ defmodule AprsWeb.MapLive.CallsignView do - -
-
-
Map Debug Panel
- -
- Map Dimensions:
- Checking... -
- -
- Leaflet Library:
- {if @debug_info.leaflet_loaded, do: "✓ Loaded", else: "⏳ Loading..."} -
- -
- Phoenix Hook:
- {if @debug_info.hook_mounted, do: "✓ Mounted", else: "⏳ Waiting..."} -
- -
- Map Initialization:
- {if @debug_info.map_initialized, do: "✓ Initialized", else: "⏳ Waiting..."} -
- -
- Map Ready:
- {if @debug_info.map_ready, do: "✓ Ready", else: "⏳ Waiting..."} -
- - <%= if length(@debug_info.errors) > 0 do %> -
- Errors: -
- <%= for error <- @debug_info.errors do %> - • {error}
- <% end %> -
- <% end %> - -
- Test Actions:
- - - - -
- -
- Console Output: -
-
-
-
- -
- Instructions: -
1. Open browser dev tools (F12)
2. Check Console tab for errors
- 3. Watch this panel for status updates
4. Use test buttons to debug issues -
-
- -
-
-
-
-
- - - """ - end -end diff --git a/lib/aprs_web/router.ex b/lib/aprs_web/router.ex index c79b3dc..12e9015 100644 --- a/lib/aprs_web/router.ex +++ b/lib/aprs_web/router.ex @@ -31,8 +31,6 @@ defmodule AprsWeb.Router do live "/enhanced", MapLive.Enhanced, :index get "/old", PageController, :map live "/status", StatusLive.Index, :index - live "/debug_map", MapLive.Debug, :index - get "/test_map", PageController, :test_map live "/packets", PacketsLive.Index, :index live "/:callsign", MapLive.CallsignView, :index