|
|
@@ -24,6 +24,10 @@ const Browser = (() => {
|
|
|
let autoScrollRaf = null;
|
|
|
let autoScrollDir = 0; // -1 up, +1 down, 0 stopped
|
|
|
|
|
|
+ // ===== Track data cache =====
|
|
|
+ let trackDataCache = {}; // trackId → API response (segments + meta)
|
|
|
+ let loadingTrackIds = new Set();
|
|
|
+
|
|
|
async function init() {
|
|
|
document.getElementById('new-dir-btn').addEventListener('click', createDirPrompt);
|
|
|
document.getElementById('upload-btn').addEventListener('click', () => {
|
|
|
@@ -517,7 +521,13 @@ const Browser = (() => {
|
|
|
|
|
|
// ===== Track Actions =====
|
|
|
|
|
|
+ function setTrackItemLoading(trackId, on) {
|
|
|
+ const el = document.querySelector(`.track-item[data-id="${trackId}"]`);
|
|
|
+ if (el) el.classList.toggle('loading-track', on);
|
|
|
+ }
|
|
|
+
|
|
|
async function openTrack(trackId) {
|
|
|
+ if (loadingTrackIds.has(trackId)) return;
|
|
|
try {
|
|
|
if (MapView.hasTrack(trackId)) {
|
|
|
MapView.removeTrack(trackId);
|
|
|
@@ -526,7 +536,20 @@ const Browser = (() => {
|
|
|
if (typeof Elevation !== 'undefined') Elevation.clear();
|
|
|
return;
|
|
|
}
|
|
|
- const data = await API.getTrackPoints(trackId);
|
|
|
+
|
|
|
+ let data = trackDataCache[trackId];
|
|
|
+ if (!data) {
|
|
|
+ loadingTrackIds.add(trackId);
|
|
|
+ setTrackItemLoading(trackId, true);
|
|
|
+ try {
|
|
|
+ data = await API.getTrackPoints(trackId);
|
|
|
+ trackDataCache[trackId] = data;
|
|
|
+ } finally {
|
|
|
+ loadingTrackIds.delete(trackId);
|
|
|
+ setTrackItemLoading(trackId, false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
MapView.addTrack(data, trackId);
|
|
|
MapView.fitTrack(trackId);
|
|
|
MapView.setCurrentTrack(trackId);
|
|
|
@@ -573,6 +596,7 @@ const Browser = (() => {
|
|
|
modal.style.display = 'none';
|
|
|
try {
|
|
|
await API.updateTrack(trackId, { name, trackType });
|
|
|
+ delete trackDataCache[trackId];
|
|
|
await reload();
|
|
|
showToast('Track updated', 'success');
|
|
|
} catch (e) {
|
|
|
@@ -584,6 +608,7 @@ const Browser = (() => {
|
|
|
async function deleteTrack(id) {
|
|
|
try {
|
|
|
MapView.removeTrack(id);
|
|
|
+ delete trackDataCache[id];
|
|
|
await API.deleteTrack(id);
|
|
|
await reload();
|
|
|
} catch (e) {
|