From 4d5f1ee375501fb39253e9571c42b2be2eeb734e Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 30 Oct 2025 22:59:47 +0000 Subject: [PATCH 1/7] recorder: render map when we have full track details rather than the 100-or-so lines we initially fetched --- apps/recorder/interface.html | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index aa8f5a1845..fd96eb18e1 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -842,23 +842,21 @@

Settings

attachTrackButtonListeners(trackContainer); downloadTrack(track.filename).then(fullTrack => { - if (trackData.Latitude) { - const coordinates = fullTrack - .filter(hasValidGPS) - .map(pt => [parseFloat(pt.Latitude), parseFloat(pt.Longitude)]); - - if (coordinates.length > 0) { - createLeafletMap(`map-${track.number}`, coordinates, fullTrack); - - let distance = 0; - for (let i = 1; i < coordinates.length; i++) distance += L.latLng(coordinates[i-1]).distanceTo(L.latLng(coordinates[i])); - const duration = fullTrack[fullTrack.length-1].Time - fullTrack[0].Time; - const hours = Math.floor(duration / 3600000), minutes = Math.floor((duration % 3600000) / 60000); - const statsEl = document.getElementById(`stats-${track.number}`); - if (statsEl) { - const d = convertDistance(distance/1000); - statsEl.innerHTML = `Distance: ${d.value.toFixed(2)} ${d.unit} | Duration: ${hours}h ${minutes}m | Points: ${coordinates.length}`; - } + const coordinates = fullTrack + .filter(hasValidGPS) + .map(pt => [parseFloat(pt.Latitude), parseFloat(pt.Longitude)]); + + if (coordinates.length > 0) { + createLeafletMap(`map-${track.number}`, coordinates, fullTrack); + + let distance = 0; + for (let i = 1; i < coordinates.length; i++) distance += L.latLng(coordinates[i-1]).distanceTo(L.latLng(coordinates[i])); + const duration = fullTrack[fullTrack.length-1].Time - fullTrack[0].Time; + const hours = Math.floor(duration / 3600000), minutes = Math.floor((duration % 3600000) / 60000); + const statsEl = document.getElementById(`stats-${track.number}`); + if (statsEl) { + const d = convertDistance(distance/1000); + statsEl.innerHTML = `Distance: ${d.value.toFixed(2)} ${d.unit} | Duration: ${hours}h ${minutes}m | Points: ${coordinates.length}`; } } From b094ce3170a2e1c97bc19a1f66a0ae535cf90d09 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 30 Oct 2025 23:00:19 +0000 Subject: [PATCH 2/7] recorder: return after `resolve()` and faster track loading faster via `==` --- apps/recorder/interface.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index fd96eb18e1..3484c27e88 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -710,7 +710,7 @@ if (lIdx >= 0) { var tries = 100; var l = data; - while (l && l.split(",")[lIdx]=="" && tries--) + while (l && l.split(",")[lIdx]==="" && tries--) l = f.readLine(); if (l) data = l; } @@ -719,6 +719,7 @@ if (!trackInfo || !("headers" in trackInfo)) { showToast("Error loading track list.", "error"); resolve(); + return; } trackInfo.headers = trackInfo.headers.split(","); trackList.push({ From 30aca3bb02eb3b4387a6d53e3d49f3f1bd494502 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 30 Oct 2025 23:01:20 +0000 Subject: [PATCH 3/7] recorder: add bangle auther info --- apps/recorder/interface.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index 3484c27e88..b9860a6129 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -414,6 +414,12 @@ const gpx = ` + + + BangleJS + + + ${title}${track.map(pt => { // Calculate cadence (steps per minute) from step count // Formula: (steps in interval * 60 seconds * 1000ms) / time elapsed in ms From f2b463d760d9202a23ef2da556a5d53cf15ecffd Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 30 Oct 2025 23:01:50 +0000 Subject: [PATCH 4/7] recorder: space out GPX tags --- apps/recorder/interface.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index b9860a6129..e78da18268 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -420,7 +420,9 @@ - ${title}${track.map(pt => { + + ${title} + ${track.map(pt => { // Calculate cadence (steps per minute) from step count // Formula: (steps in interval * 60 seconds * 1000ms) / time elapsed in ms // Simplified to: steps * 30000 / time_ms (since 60 * 1000 / 2 = 30000) From 6b1d0e1ff70b54cf4fe1009e92396524f6d2bf13 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Thu, 30 Oct 2025 23:01:58 +0000 Subject: [PATCH 5/7] recorder: add note about track type --- apps/recorder/interface.html | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index e78da18268..066845cbdf 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -411,6 +411,7 @@ // check track validity after filtering if (!track?.[0]?.Time) return showToast("Error in trackfile (no time or empty).", "error"); let lastTime = 0; + //const trackType = ... -> `${trackType}` const gpx = ` From 8ade24a2f16b4003cda7c40b684c795cc4f830c7 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Fri, 31 Oct 2025 17:53:55 +0000 Subject: [PATCH 6/7] recorder: update author name & link --- apps/recorder/interface.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index 066845cbdf..729b87188a 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -417,8 +417,8 @@ - BangleJS - + Bangle.js + From ae1a6d9c2d84a19df8003d3daa9f9e3ab39f5910 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Tue, 11 Nov 2025 12:09:20 +0000 Subject: [PATCH 7/7] recorder: fix single-track download --- apps/recorder/interface.html | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/recorder/interface.html b/apps/recorder/interface.html index 729b87188a..1f11b87615 100644 --- a/apps/recorder/interface.html +++ b/apps/recorder/interface.html @@ -464,7 +464,7 @@ return o; } -async function downloadTrack(filename) { +async function downloadTrack(filename) { // filename: string function parse(data) { const lines = data.trim().split("\n"), headers = lines.shift().split(","); return lines.map(l=>trackLineToObject(headers, l)).filter(t => t.Time); @@ -487,7 +487,7 @@ return document.getElementById(`track-download-${trackNumber}`).checked; } -async function downloadTracks(tracks, saveCb) { +async function downloadTracks(tracks, saveCb) { // tracks: [{ filename: string, number: number }] for(const track of tracks){ const lines = await downloadTrack(track.filename); const title = `Bangle.js Track ${track.number}`; @@ -910,18 +910,19 @@

Settings

if (!filename || !trackid) return; + const tracks = [{ filename, number: trackid }]; switch(task) { case "delete": await confirmDelete(button, [filename]); break; case "downloadkml": - await downloadTracks([filename], track => saveKML(track, `Bangle.js Track ${trackid}`)); + await downloadTracks(tracks, track => saveKML(track, `Bangle.js Track ${trackid}`)); break; case "downloadgpx": - await downloadTracks([filename], track => saveGPX(track, `Bangle.js Track ${trackid}`)); + await downloadTracks(tracks, track => saveGPX(track, `Bangle.js Track ${trackid}`)); break; case "downloadcsv": - await downloadTracks([filename], track => saveCSV(track, `Bangle.js Track ${trackid}`)); + await downloadTracks(tracks, track => saveCSV(track, `Bangle.js Track ${trackid}`)); break; } });