diff --git a/assets/js/app.js b/assets/js/app.js index 1bbca15..727741c 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -31,6 +31,8 @@ if (!csrfToken) { import MapAPRSMap from "./map"; // Import error boundary hook import ErrorBoundary from "./hooks/error_boundary"; +// Import info map hook +import { InfoMap } from "./hooks/info_map"; // Responsive Slideover Hook let ResponsiveSlideoverHook = { @@ -105,6 +107,7 @@ Hooks.APRSMap = MapAPRSMap; Hooks.ResponsiveSlideoverHook = ResponsiveSlideoverHook; Hooks.BodyClassHook = BodyClassHook; Hooks.ErrorBoundary = ErrorBoundary; +Hooks.InfoMap = InfoMap; // Register weather chart hooks from TypeScript import { WeatherChartHooks } from "./features/weather_charts"; diff --git a/assets/js/hooks/info_map.js b/assets/js/hooks/info_map.js new file mode 100644 index 0000000..ed5d907 --- /dev/null +++ b/assets/js/hooks/info_map.js @@ -0,0 +1,89 @@ +// Simple map hook for displaying a single station on the info page +export const InfoMap = { + mounted() { + // Check if Leaflet is available + if (typeof L === "undefined") { + console.error("Leaflet not loaded for InfoMap"); + return; + } + + // Get data from element attributes + const lat = parseFloat(this.el.dataset.lat); + const lon = parseFloat(this.el.dataset.lon); + const zoom = parseInt(this.el.dataset.zoom) || 13; + const callsign = this.el.dataset.callsign; + const symbolHtml = this.el.dataset.symbolHtml; + + // Validate coordinates + if (isNaN(lat) || isNaN(lon)) { + console.error("Invalid coordinates for InfoMap"); + return; + } + + // Initialize the map + try { + this.map = L.map(this.el, { + center: [lat, lon], + zoom: zoom, + scrollWheelZoom: false, // Disable scroll zoom for embedded maps + zoomControl: true, + attributionControl: true + }); + + // Add tile layer + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap', + maxZoom: 19 + }).addTo(this.map); + + // Create marker icon + let markerIcon; + if (symbolHtml) { + // Use the APRS symbol if provided + markerIcon = L.divIcon({ + html: symbolHtml, + className: 'aprs-info-marker', + iconSize: [32, 32], + iconAnchor: [16, 16] + }); + } else { + // Default marker + markerIcon = L.divIcon({ + html: `
`, + className: '', + iconSize: [24, 24], + iconAnchor: [12, 12] + }); + } + + // Add marker for the station + const marker = L.marker([lat, lon], { icon: markerIcon }) + .addTo(this.map) + .bindPopup(`${callsign}| - {gettext("Callsign")} - | -- {gettext("Distance & Direction")} - | -- {gettext("Last Heard")} - | -
|---|---|---|
|
-
- <.link navigate={~p"/info/#{ssid_info.callsign}"} class="link link-primary">
- {ssid_info.callsign}
+
+
-
- {render_symbol_html(ssid_info.packet)}
-
- <% end %>
- |
- - <%= if ssid_info.packet && ssid_info.packet.lat && ssid_info.packet.lon && @packet && @packet.lat && @packet.lon do %> - <% dist = - haversine( - @packet.lat, - @packet.lon, - ssid_info.packet.lat, - ssid_info.packet.lon - ) %> - <% course = - calculate_course( - @packet.lat, - @packet.lon, - ssid_info.packet.lat, - ssid_info.packet.lon - ) %> - <% locale = Map.get(assigns, :locale, "en") %> - <%= if course do %> - {format_distance(dist, locale)} @ {Float.round(course, 0)}° - <% else %> - {format_distance(dist, locale)} - <% end %> - <% else %> - - - <% end %> - | -- <%= if ssid_info.last_heard do %> - - {ssid_info.last_heard.time_ago} - - <% else %> - {gettext("Unknown")} - <% end %> - | -
| + {gettext("Callsign")} + | ++ {gettext("Distance & Direction")} + | ++ {gettext("Last Heard")} + | +
|---|---|---|
|
+
+ <.link navigate={~p"/info/#{ssid_info.callsign}"} class="link link-primary">
+ {ssid_info.callsign}
+
+ <%= if ssid_info.packet do %>
+ <% {symbol_table, symbol_code} =
+ AprsmeWeb.AprsSymbol.extract_from_packet(ssid_info.packet) %>
+ <% display_symbol =
+ if symbol_table && String.match?(symbol_table, ~r/^[A-Z0-9]$/),
+ do: symbol_table,
+ else:
+ "#{AprsmeWeb.AprsSymbol.normalize_symbol_table(symbol_table)}#{AprsmeWeb.AprsSymbol.normalize_symbol_code(symbol_code)}" %>
+
+
+ {render_symbol_html(ssid_info.packet)}
+
+ <% end %>
+ |
+ + <%= if ssid_info.packet && ssid_info.packet.lat && ssid_info.packet.lon && @packet && @packet.lat && @packet.lon do %> + <% dist = + haversine( + @packet.lat, + @packet.lon, + ssid_info.packet.lat, + ssid_info.packet.lon + ) %> + <% course = + calculate_course( + @packet.lat, + @packet.lon, + ssid_info.packet.lat, + ssid_info.packet.lon + ) %> + <% locale = Map.get(assigns, :locale, "en") %> + <%= if course do %> + {format_distance(dist, locale)} @ {Float.round(course, 0)}° + <% else %> + {format_distance(dist, locale)} + <% end %> + <% else %> + - + <% end %> + | ++ <%= if ssid_info.last_heard do %> + + {ssid_info.last_heard.time_ago} + + <% else %> + {gettext("Unknown")} + <% end %> + | +