diff --git a/app/resources/js/Result.js b/app/resources/js/Result.js index 3b968f8dd4b44b143393ee2a278e190dc244de69..39b58e94f386de2b45dd0c25e2f7dd90bb654a2a 100644 --- a/app/resources/js/Result.js +++ b/app/resources/js/Result.js @@ -38,7 +38,7 @@ export class Result { enable_actions = false, source = "search", rank = 0, - route = null, + route = null ) { this.load_data = load_data; this.actions_enabled = enable_actions; @@ -50,20 +50,23 @@ export class Result { } load() { - return new Promise(resolve => { + return new Promise((resolve) => { if (typeof this.load_data == "object") { if (this.load_data) this.data = this.load_data; this.#createDomElement(); + this.dom_element.dispatchEvent(new Event("load")); return resolve(); } else if (typeof this.load_data == "string") { let detail_match = this.load_data.match(/^(N|W|R)(\d+)$/); if (detail_match) { // Add waypoint from lookup - this.#lookupWaypoint(detail_match[1] + detail_match[2]).then(() => { - this.#createDomElement(); - this.dom_element.dispatchEvent(new Event("load")); - return; - }).then(() => resolve()); + this.#lookupWaypoint(detail_match[1] + detail_match[2]) + .then(() => { + this.#createDomElement(); + this.dom_element.dispatchEvent(new Event("load")); + return; + }) + .then(() => resolve()); } else if (this.load_data.startsWith("gps")) { this.#getFromGPS(() => { this.#createDomElement(); @@ -72,7 +75,9 @@ export class Result { }); } } else { - throw new Error(`"${typeof this.load_data}" cannot be parsed to a result`); + throw new Error( + `"${typeof this.load_data}" cannot be parsed to a result` + ); } }); } @@ -115,11 +120,11 @@ export class Result { accuracy: coords.accuracy, altitudeAccuracy: coords.altitudeAccuracy, heading: coords.heading, - speed: coords.speed - } + speed: coords.speed, + }, }, lon: position.coords.longitude, - lat: position.coords.latitude + lat: position.coords.latitude, }; let bbox = turf.bbox(circle); @@ -137,13 +142,19 @@ export class Result { frequency_high_enough = true; } - if (!this.navigation_available && accuracy_high_enough && frequency_high_enough) { + if ( + !this.navigation_available && + accuracy_high_enough && + frequency_high_enough + ) { this.navigation_available = true; this.dom_element.dispatchEvent(new Event("navigation_available")); } if (position.timestamp - lastUpdate >= maximumAge) { lastUpdate = position.timestamp; - this.dom_element.dispatchEvent(new CustomEvent("update", { detail: position })); + this.dom_element.dispatchEvent( + new CustomEvent("update", { detail: position }) + ); } } }; @@ -168,7 +179,9 @@ export class Result { this.error_code = error.code; callback(); } else { - this.dom_element.dispatchEvent(new CustomEvent("update", { detail: null })); + this.dom_element.dispatchEvent( + new CustomEvent("update", { detail: null }) + ); } }; @@ -178,13 +191,21 @@ export class Result { maximumAge: 60000, }; - gpsManager.getCurrentPosition(position => { - position_callback(position); - // Try to upgrade to a high accuracy position - options.enableHighAccuracy = true; - options.maximumAge = 500; - this.geolocation_watch_id = gpsManager.watchPosition(position_callback.bind(this), error_callback, options); - }, error_callback, options); + gpsManager.getCurrentPosition( + (position) => { + position_callback(position); + // Try to upgrade to a high accuracy position + options.enableHighAccuracy = true; + options.maximumAge = 500; + this.geolocation_watch_id = gpsManager.watchPosition( + position_callback.bind(this), + error_callback, + options + ); + }, + error_callback, + options + ); } async #lookupWaypoint(osm_id) { diff --git a/app/resources/js/RouteFinder.js b/app/resources/js/RouteFinder.js index 33f3248ee204f46ecb1350d1618dca143a10f6c9..390408fff8aee0d5a01cc5d6d81d3195751813dd 100644 --- a/app/resources/js/RouteFinder.js +++ b/app/resources/js/RouteFinder.js @@ -99,58 +99,62 @@ class RouteFinder { } } // Add GPS options - await gpsManager.isGPSAvailable().then((gps_available) => { - this.htmlmodule.classList.remove("navigation-enabled"); - if ( - gps_available && - waypoints.length + this.waypoints.length == 1 && - !waypoints[0].startsWith("gps") - ) { - waypoints.unshift("gps"); - } - }); + if ( + waypoints.length + this.waypoints.length == 1 && + !waypoints[0].source.startsWith("gps") + ) { + waypoints.unshift("gps"); + } + let waypoint_load_promises = []; + /* + + */ for (const [index, waypoint] of waypoints.entries()) { - if (waypoint instanceof Result) { - this.addWaypoint(waypoint); - await this.calculateRoutes(); - this.updateInterface(); - continue; - } - let detail_match = waypoint.match(/^(N|W|R)(\d+)$/); let new_waypoint = null; - if (detail_match) { + + if (waypoint instanceof Result) { + new_waypoint = waypoint; + } else if (waypoint.startsWith("gps")) { + new_waypoint = new Result(waypoint, false, "gps"); + } else if (typeof waypoint == "object" && waypoint.load_data) { new_waypoint = new Result( - detail_match[1] + detail_match[2], + waypoint.load_data, false, - "lookup" + waypoint.source, + 0, + waypoint.route ); - } else if (waypoint.startsWith("gps")) { - new_waypoint = new Result(waypoint, false, "gps"); + } else { + let detail_match = waypoint.match(/^(N|W|R)(\d+)$/); + if (detail_match) { + new_waypoint = new Result( + detail_match[1] + detail_match[2], + false, + "lookup" + ); + } } if (new_waypoint) { - new_waypoint.rank = this.waypoints.length; - new_waypoint.dom_element.addEventListener( - "load", - async (e) => { - let all_routes_calculated = await this.calculateRoutes(); - this.updateInterface(); - if (!mapposition) { - this.fitRoutesOnMap(); - } - if (this.navigation_active && all_routes_calculated) { - this.startNavigation(); - } - }, - { once: true } - ); this.addWaypoint(new_waypoint); - new_waypoint.load(); // Now that all event listeners are registered we can load the waypoint + waypoint_load_promises.push(new_waypoint.load()); // Now that all event listeners are registered we can load the waypoint } } - if (waypoints.length == 0) { + if (waypoint_load_promises.length == 0) { this.updateInterface(); this.fitRoutesOnMap(); + } else { + Promise.all(waypoint_load_promises).then(() => { + return this.calculateRoutes().then((all_routes_calculated) => { + this.updateInterface(); + if (!mapposition) { + this.fitRoutesOnMap(); + } + if (this.navigation_active && all_routes_calculated) { + this.startNavigation(); + } + }); + }); } if (mapposition) { @@ -163,8 +167,6 @@ class RouteFinder { }, { user: false } ); - } else { - this.fitRoutesOnMap(); } } @@ -175,7 +177,11 @@ class RouteFinder { gpsManager.clearWatch(this.waypoints[index].geolocation_watch_id); } if (this.waypoints[index].route) this.waypoints[index].route.hidePopups(); - if (index > 0 && this.waypoints[index - 1].route && this.waypoints[index - 1].route.data) { + if ( + index > 0 && + this.waypoints[index - 1].route && + this.waypoints[index - 1].route.data + ) { this.waypoints[index - 1].route.hidePopups(); this.waypoints[index - 1].route = null; } @@ -190,6 +196,14 @@ class RouteFinder { this.waypoints.push(waypoint); } this.updateInterface(); + // Register Event handler for load event + waypoint.dom_element.addEventListener( + "load", + async (e) => { + this.updateInterface(); + }, + { once: true } + ); // Register Event handler for gps updates if ((first || this.waypoints.length == 1) && waypoint.source == "gps") { waypoint.dom_element.addEventListener( @@ -336,9 +350,14 @@ class RouteFinder { }, 250); } ); - gps_waypoint.load().then(() => { - this.addWaypoint(gps_waypoint, true); - }); + this.addWaypoint(gps_waypoint, true); + gps_waypoint + .load() + .then(() => this.calculateRoutes()) + .then(() => { + this.updateInterface(); + this.updateState(); + }); }; } @@ -578,7 +597,7 @@ class RouteFinder { else bbox_collection = turf.featureCollection([bbox]); } let bbox = turf.bbox(bbox_collection); - map.fitBounds(new LngLatBounds(bbox), { duration: 250 }); + map.fitBounds(new LngLatBounds(bbox), { duration: 250, padding: 25 }); } clearInterface() { @@ -588,7 +607,7 @@ class RouteFinder { /** * Function called when map is loaded and GPS Features become available */ - enableGps() { } + enableGps() {} /** * Cleanup Code when module is closed