Summarize LiveTrack sessions and prune stale ones
Fetching a session's track now also grabs its summary (name, activity type, distance, duration) from the same page and stores it — sessions the panel has actually shown replace their raw UUID with that summary, and are kept indefinitely regardless of age. A session nobody ever opened (no summary) is more likely test/dead data than something worth keeping, so it's dropped automatically after 48h.
This commit is contained in:
1 parent
f4b5237f01
commit
0ee98d8f07
5 files changed
+175
-47
No files matched your search
@@ -471,13 +471,16 @@ html, body {
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
.livetrack-panel__id {
|
||||
font-family: monospace;
|
||||
.livetrack-panel__label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.livetrack-panel__label--id {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.livetrack-panel__time {
|
||||
flex-shrink: 0;
|
||||
color: #888;
|
||||
|
||||
+31
-5
@@ -68,7 +68,7 @@ export class LiveTrackPanelControl {
|
||||
return;
|
||||
}
|
||||
|
||||
sessions.forEach(({ id, received_at }) => {
|
||||
sessions.forEach(({ id, received_at, summary }) => {
|
||||
const li = document.createElement("li");
|
||||
li.className = "livetrack-panel__item";
|
||||
|
||||
@@ -76,16 +76,18 @@ export class LiveTrackPanelControl {
|
||||
button.type = "button";
|
||||
button.className = "livetrack-panel__row";
|
||||
button.classList.toggle("active", id === this._activeSessionId);
|
||||
button.title = id;
|
||||
|
||||
const idSpan = document.createElement("span");
|
||||
idSpan.className = "livetrack-panel__id";
|
||||
idSpan.textContent = id;
|
||||
const labelSpan = document.createElement("span");
|
||||
labelSpan.className = "livetrack-panel__label";
|
||||
labelSpan.classList.toggle("livetrack-panel__label--id", !summary);
|
||||
labelSpan.textContent = summary ? summaryLabel(summary) : id;
|
||||
|
||||
const timeSpan = document.createElement("span");
|
||||
timeSpan.className = "livetrack-panel__time";
|
||||
timeSpan.textContent = new Date(received_at).toLocaleString();
|
||||
|
||||
button.append(idSpan, timeSpan);
|
||||
button.append(labelSpan, timeSpan);
|
||||
button.addEventListener("click", () => this._toggleTrack(id, button));
|
||||
li.appendChild(button);
|
||||
this._list.appendChild(li);
|
||||
@@ -110,6 +112,10 @@ export class LiveTrackPanelControl {
|
||||
this._showTrack(this._geojson);
|
||||
this._activeSessionId = id;
|
||||
button.classList.add("active");
|
||||
// The fetch above also computed and stored a summary server-side
|
||||
// (see LiveTrackClient.summarize) — reload so this row picks it up
|
||||
// instead of showing the raw id from here on.
|
||||
this._loadSessions();
|
||||
} finally {
|
||||
button.classList.remove("loading");
|
||||
}
|
||||
@@ -170,3 +176,23 @@ export class LiveTrackPanelControl {
|
||||
if (this._map.getSource(TRACK_SOURCE)) this._map.removeSource(TRACK_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
function summaryLabel({ session_name, activity_type, distance_meters, duration_secs }) {
|
||||
const parts = [];
|
||||
if (activity_type) parts.push(titleCase(activity_type));
|
||||
if (typeof distance_meters === "number") parts.push(`${(distance_meters / 1000).toFixed(1)} km`);
|
||||
if (typeof duration_secs === "number") parts.push(formatDuration(duration_secs));
|
||||
const stats = parts.join(" · ");
|
||||
if (session_name && stats) return `${session_name} — ${stats}`;
|
||||
return session_name || stats || "Untitled session";
|
||||
}
|
||||
|
||||
function titleCase(text) {
|
||||
return text.charAt(0) + text.slice(1).toLowerCase();
|
||||
}
|
||||
|
||||
function formatDuration(totalSeconds) {
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
return hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
|
||||
}
|
||||
Reference in new issue
Block a user