Fix Leaflet library loading race condition and enable Redis-free development

- Fix race condition in map bundle loading by waiting for script to load before initializing map
- Ensure Leaflet is properly exposed as window.L in map bundle
- Add Leaflet availability check in map initialization function
- Disable Exq background jobs in development environment to remove Redis dependency
- Remove invalid TelemetryMetricsPrometheus plug from endpoint
- Application now starts successfully without Redis in development mode

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Graham McIntire 2025-07-27 12:20:23 -05:00
parent 863000d6b8
commit 8ddcb8000f
No known key found for this signature in database
5 changed files with 63 additions and 13 deletions

View file

@ -129,11 +129,27 @@ let Hooks = {};
Hooks.APRSMap = {
...MapAPRSMap,
mounted() {
if (window.VendorLoader) {
window.VendorLoader.loadMap();
}
if (MapAPRSMap.mounted) {
MapAPRSMap.mounted.call(this);
const self = this;
if (window.VendorLoader && !window.mapBundleLoaded) {
// Load map bundle and wait for it to complete
const script = document.createElement('script');
script.src = window.VendorLoader.mapBundleUrl;
script.onload = () => {
window.mapBundleLoaded = true;
// Now call the original mounted function
if (MapAPRSMap.mounted) {
MapAPRSMap.mounted.call(self);
}
};
script.onerror = () => {
console.error("Failed to load map bundle");
};
document.head.appendChild(script);
} else {
// Map bundle already loaded, proceed immediately
if (MapAPRSMap.mounted) {
MapAPRSMap.mounted.call(this);
}
}
}
};
@ -141,11 +157,27 @@ Hooks.APRSMap = {
Hooks.InfoMap = {
...InfoMap,
mounted() {
if (window.VendorLoader) {
window.VendorLoader.loadMap();
}
if (InfoMap.mounted) {
InfoMap.mounted.call(this);
const self = this;
if (window.VendorLoader && !window.mapBundleLoaded) {
// Load map bundle and wait for it to complete
const script = document.createElement('script');
script.src = window.VendorLoader.mapBundleUrl;
script.onload = () => {
window.mapBundleLoaded = true;
// Now call the original mounted function
if (InfoMap.mounted) {
InfoMap.mounted.call(self);
}
};
script.onerror = () => {
console.error("Failed to load map bundle");
};
document.head.appendChild(script);
} else {
// Map bundle already loaded, proceed immediately
if (InfoMap.mounted) {
InfoMap.mounted.call(this);
}
}
}
};

View file

@ -2,5 +2,10 @@
import "../vendor/js/leaflet-minimal.js";
import "../vendor/js/plugins-optimized.js";
// Ensure Leaflet is available as window.L (standard convention)
if (window.leaflet && !window.L) {
window.L = window.leaflet;
}
// Mark bundle as loaded
window.mapBundleLoaded = true;

View file

@ -157,6 +157,17 @@ let MapAPRSMap = {
initializeMap(initialCenter: CenterData, initialZoom: number) {
const self = this as unknown as LiveViewHookContext;
// Check if Leaflet is still available
if (typeof window.L === "undefined") {
console.error("Leaflet library not loaded!");
self.handleFatalError("Leaflet library not available");
return;
}
// Create a local reference to Leaflet for this function
const L = window.L;
// Ensure the element and its parent exist
if (!self.el || !self.el.parentNode) {
console.warn("Map element or parent not found, retrying...");

View file

@ -72,6 +72,11 @@ config :aprsme, AprsmeWeb.Endpoint,
# Run `mix help phx.gen.cert` for more information.
config :aprsme, dev_routes: true
# Disable Exq in development (no Redis required)
# Jobs that would normally run in the background will be skipped
config :exq,
start_on_application: false
# Mailer configuration for development
# Using Swoosh.Adapters.Local from config.exs which stores emails locally
# Access sent emails at http://localhost:4000/dev/mailbox

View file

@ -56,8 +56,5 @@ defmodule AprsmeWeb.Endpoint do
# Health check endpoint
plug AprsmeWeb.Plugs.HealthCheck
# Prometheus metrics endpoint
plug TelemetryMetricsPrometheus
plug AprsmeWeb.Router
end