Auto-refresh a track while its session is still live
Opening a session that's still recording (active in its summary) now re-fetches every 30s and updates the map in place, instead of freezing at whatever the track looked like when first opened. Stops on its own once the session ends, or immediately if switched away from.
This commit is contained in:
1 parent
6b8ea27e22
commit
8d3c126a14
1 file changed
+45
-7
+45
-7
@@ -5,6 +5,10 @@ import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
|
||||
const SESSIONS_URL = "/api/livetrack/sessions";
|
||||
const TRACK_SOURCE = "livetrack-track";
|
||||
const TRACK_COLOR = "#7209b7";
|
||||
// Garmin devices post a new point roughly every 15s (postTrackPointFrequency
|
||||
// in the session data) — polling twice that often would just re-fetch the
|
||||
// same 400+KB page for nothing most of the time.
|
||||
const REFRESH_INTERVAL_MS = 30000;
|
||||
|
||||
// A sidebar icon that opens a side panel listing Garmin LiveTrack sessions
|
||||
// received via the webhook (see docs/deployment.adoc). Clicking one fetches
|
||||
@@ -17,6 +21,7 @@ export class LiveTrackPanelControl {
|
||||
this._geojson = null;
|
||||
this._hoverPopup = null;
|
||||
this._pointInteractivityRegistered = false;
|
||||
this._refreshTimer = null;
|
||||
|
||||
// setStyle() (switching the Online/Offline base map) tears down all
|
||||
// custom sources and layers — put the track back afterwards, same as
|
||||
@@ -109,13 +114,7 @@ export class LiveTrackPanelControl {
|
||||
|
||||
button.classList.add("loading");
|
||||
try {
|
||||
const response = await fetch(`/api/livetrack/sessions/${encodeURIComponent(id)}/track`);
|
||||
if (!response.ok) {
|
||||
const { error } = await response.json().catch(() => ({}));
|
||||
window.alert(error || "Could not load track.");
|
||||
return;
|
||||
}
|
||||
this._geojson = await response.json();
|
||||
this._geojson = await this._fetchTrack(id);
|
||||
this._showTrack(this._geojson);
|
||||
this._activeSessionId = id;
|
||||
button.classList.add("active");
|
||||
@@ -123,11 +122,48 @@ export class LiveTrackPanelControl {
|
||||
// (see LiveTrackClient.summarize) — reload so this row picks it up
|
||||
// instead of showing the raw id from here on.
|
||||
this._loadSessions();
|
||||
this._scheduleRefresh(id);
|
||||
} catch (err) {
|
||||
window.alert(err.message);
|
||||
} finally {
|
||||
button.classList.remove("loading");
|
||||
}
|
||||
}
|
||||
|
||||
async _fetchTrack(id) {
|
||||
const response = await fetch(`/api/livetrack/sessions/${encodeURIComponent(id)}/track`);
|
||||
if (!response.ok) {
|
||||
const { error } = await response.json().catch(() => ({}));
|
||||
throw new Error(error || "Could not load track.");
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// Re-fetches on a timer for as long as the session is still recording
|
||||
// (properties.active on the Point feature — see LiveTrackClient), so an
|
||||
// in-progress activity's line keeps growing instead of staying frozen at
|
||||
// whatever it looked like when first opened. Stops on its own once the
|
||||
// session ends, or immediately if the session is switched away from or
|
||||
// toggled off in the meantime.
|
||||
_scheduleRefresh(id) {
|
||||
if (!this._geojson.features[1].properties.active) return;
|
||||
|
||||
this._refreshTimer = setTimeout(async () => {
|
||||
if (this._activeSessionId !== id) return;
|
||||
try {
|
||||
const geojson = await this._fetchTrack(id);
|
||||
if (this._activeSessionId !== id) return;
|
||||
this._geojson = geojson;
|
||||
this._map.getSource(TRACK_SOURCE)?.setData(geojson);
|
||||
this._loadSessions();
|
||||
} catch {
|
||||
// Transient fetch failure — leave the track as-is and try again
|
||||
// next tick rather than interrupting with an alert.
|
||||
}
|
||||
this._scheduleRefresh(id);
|
||||
}, REFRESH_INTERVAL_MS);
|
||||
}
|
||||
|
||||
_showTrack(geojson, { fit = true } = {}) {
|
||||
if (this._map.getSource(TRACK_SOURCE)) return;
|
||||
|
||||
@@ -202,6 +238,8 @@ export class LiveTrackPanelControl {
|
||||
}
|
||||
|
||||
_removeTrack() {
|
||||
clearTimeout(this._refreshTimer);
|
||||
this._refreshTimer = null;
|
||||
this._activeSessionId = null;
|
||||
this._geojson = null;
|
||||
this._hoverPopup?.remove();
|
||||
|
||||
Reference in new issue
Block a user