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, """ - - -
- - -