overhaul gpx creation and usage
This commit is contained in:
+40
-26
@@ -1,6 +1,10 @@
|
||||
(function (ns, $) {
|
||||
'use strict';
|
||||
|
||||
const DROPDOWN_ANIMATION_MS = 180;
|
||||
let routeControlOpen = false;
|
||||
let routeControlCloseTimer = null;
|
||||
|
||||
const state = {
|
||||
routes: [],
|
||||
localRoutes: [],
|
||||
@@ -319,6 +323,9 @@
|
||||
.prop('hidden', false)
|
||||
.text(ns.I18n.t("app.pause-hint"));
|
||||
showNavigation(ns.I18n.t("app.route-paused"), $('#navigation-distance').text() || '–');
|
||||
$('#navigation-arrow').prop('hidden', true);
|
||||
$('#route-navigation-arrow').prop('hidden', true);
|
||||
$('#route-navigation-mode').text(ns.I18n.t('app.route-paused'));
|
||||
updateRouteControls();
|
||||
}
|
||||
|
||||
@@ -421,7 +428,7 @@
|
||||
function poiMetrics(position) {
|
||||
if (!position || !state.route?.pois?.length) return [];
|
||||
const heading = effectiveHeading(position);
|
||||
return state.route.pois.map(poi => {
|
||||
return state.route.pois.filter(poi => Number.isFinite(poi.lat) && Number.isFinite(poi.lon)).map(poi => {
|
||||
const distance = ns.Distance.meters(position, poi);
|
||||
const bearing = ns.Distance.bearing(position, poi);
|
||||
return {
|
||||
@@ -498,49 +505,41 @@
|
||||
: ns.I18n.t("app.next-station", { value1: metric.poi.title }),
|
||||
`${distance} m`
|
||||
);
|
||||
$('#navigation-footer').attr(
|
||||
$('#station-navigation').attr(
|
||||
'aria-label',
|
||||
ns.I18n.t("app.next-station-distance", { value1: metric.poi.title, value2: distance })
|
||||
);
|
||||
}
|
||||
|
||||
function showRoutePointNavigation(position, progress) {
|
||||
const arrow = $('#route-navigation-arrow');
|
||||
const mode = $('#route-navigation-mode');
|
||||
if (!progress) {
|
||||
$('#navigation-arrow').css('transform', 'rotate(0deg)');
|
||||
showNavigation(ns.I18n.t("app.path.missing"), '–');
|
||||
arrow.css('transform', 'rotate(0deg)').prop('hidden', true);
|
||||
mode.text(ns.I18n.t('app.path.missing'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (progress.reached) {
|
||||
$('#navigation-arrow').css('transform', 'rotate(0deg)');
|
||||
showNavigation(ns.I18n.t("app.destination-reached"), '0 m');
|
||||
$('#navigation-footer').attr('aria-label', ns.I18n.t("app.destination-reached"));
|
||||
arrow.css('transform', 'rotate(0deg)').prop('hidden', true);
|
||||
mode.text(ns.I18n.t('app.destination-reached'));
|
||||
return;
|
||||
}
|
||||
const bearing = ns.Distance.bearing(position, progress.target);
|
||||
const heading = effectiveHeading(position);
|
||||
const rotation = heading == null
|
||||
? bearing
|
||||
: ns.Distance.normalizeDegrees(bearing - heading);
|
||||
const distance = Math.round(progress.distance);
|
||||
$('#navigation-arrow').css('transform', `rotate(${rotation.toFixed(1)}deg)`);
|
||||
showNavigation(
|
||||
heading == null ? ns.I18n.t("app.next-path-point-north") : ns.I18n.t("app.next-path-point"),
|
||||
`${distance} m`
|
||||
);
|
||||
$('#navigation-footer').attr(
|
||||
'aria-label',
|
||||
ns.I18n.t("app.next-path-point-distance", { value1: distance })
|
||||
);
|
||||
const rotation = heading == null ? bearing : ns.Distance.normalizeDegrees(bearing - heading);
|
||||
arrow.prop('hidden', false).css('transform', `rotate(${rotation.toFixed(1)}deg)`);
|
||||
mode.text(ns.I18n.t(heading == null ? 'app.next-path-point-north' : 'app.next-path-point'));
|
||||
}
|
||||
|
||||
function updateNavigation(position) {
|
||||
if (state.routeState !== 'running') return;
|
||||
const progress = updateRouteProgress(position);
|
||||
showRoutePointNavigation(position, progress);
|
||||
const metrics = updatePoiIndicators(position);
|
||||
const nextPoi = nearestPendingPoi(metrics);
|
||||
$('#navigation-arrow').prop('hidden', !nextPoi);
|
||||
if (nextPoi) showPoiNavigation(position, nextPoi);
|
||||
else showRoutePointNavigation(position, progress);
|
||||
else showNavigation(ns.I18n.t('recorder.no-station'), '–');
|
||||
}
|
||||
|
||||
function updateHeading(heading) {
|
||||
@@ -659,8 +658,23 @@
|
||||
}
|
||||
|
||||
function setRouteControlOpen(open) {
|
||||
$('#route-control-dropdown').prop('hidden', !open);
|
||||
$('#route-control-button').attr('aria-expanded', String(open));
|
||||
routeControlOpen = Boolean(open);
|
||||
globalThis.clearTimeout(routeControlCloseTimer);
|
||||
routeControlCloseTimer = null;
|
||||
const dropdown = $('#route-control-dropdown');
|
||||
$('#route-control-button').attr('aria-expanded', String(routeControlOpen));
|
||||
if (routeControlOpen) {
|
||||
dropdown.prop('hidden', false);
|
||||
const nextFrame = globalThis.requestAnimationFrame ?? (callback => callback());
|
||||
nextFrame(() => nextFrame(() => {
|
||||
if (routeControlOpen) dropdown.addClass('is-open');
|
||||
}));
|
||||
} else {
|
||||
dropdown.removeClass('is-open');
|
||||
routeControlCloseTimer = globalThis.setTimeout(() => {
|
||||
if (!routeControlOpen) dropdown.prop('hidden', true);
|
||||
}, DROPDOWN_ANIMATION_MS);
|
||||
}
|
||||
}
|
||||
|
||||
async function selectRoute(source, id) {
|
||||
@@ -718,7 +732,7 @@
|
||||
});
|
||||
|
||||
activate('#route-control-button', function () {
|
||||
setRouteControlOpen($('#route-control-dropdown').prop('hidden'));
|
||||
setRouteControlOpen(!routeControlOpen);
|
||||
});
|
||||
|
||||
activate('.route-control-actions #route-control-new', function () {
|
||||
@@ -731,7 +745,7 @@
|
||||
});
|
||||
|
||||
$(document).on('pointerup', event => {
|
||||
if ($('#route-control-dropdown').prop('hidden')) return;
|
||||
if (!routeControlOpen) return;
|
||||
if ($(event.target).closest('.route-control').length) return;
|
||||
setRouteControlOpen(false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user