// Guest-mode local GPX viewer β no backend, no auth required.
const LocalViewer = (() => {
let tracks = {}; // id β { data: {segments,meta}, visible: bool }
let nextId = 0;
let currentId = null; // track shown in info panel / elevation chart
// ===== Public =====
function init() {
setupSidebar();
setupMapDrop();
}
// ===== Sidebar =====
function setupSidebar() {
// Replace logged-in actions with a simple "Open GPX" button
document.getElementById('browser-actions').innerHTML = `
`;
document.getElementById('local-open-btn').addEventListener('click', () => {
document.getElementById('local-file-input').click();
});
document.getElementById('local-file-input').addEventListener('change', (e) => {
handleFiles(Array.from(e.target.files));
e.target.value = '';
});
// Clear breadcrumb β not relevant in guest mode
document.getElementById('breadcrumb').innerHTML =
'Local viewer';
renderList();
}
// ===== Map drop zone =====
function setupMapDrop() {
const mc = document.getElementById('map-container');
mc.addEventListener('dragover', (e) => {
if (e.dataTransfer.types.includes('Files')) {
e.preventDefault();
mc.classList.add('drag-over');
}
});
mc.addEventListener('dragleave', (e) => {
if (!mc.contains(e.relatedTarget)) mc.classList.remove('drag-over');
});
mc.addEventListener('drop', (e) => {
e.preventDefault();
mc.classList.remove('drag-over');
const files = Array.from(e.dataTransfer.files)
.filter(f => f.name.toLowerCase().endsWith('.gpx'));
if (files.length) handleFiles(files);
});
}
// ===== File loading =====
async function handleFiles(files) {
for (const file of files) {
try {
const text = await file.text();
const data = parseGPX(text, file.name);
const id = 'local_' + (nextId++);
tracks[id] = { data, visible: false };
toggleTrack(id); // open immediately
} catch (e) {
showToast('Error reading ' + file.name + ': ' + e.message, 'error');
}
}
}
// ===== Track toggling =====
function toggleTrack(id) {
const entry = tracks[id];
if (!entry) return;
if (entry.visible) {
MapView.removeTrack(id);
entry.visible = false;
if (currentId === id) {
currentId = null;
MapView.setCurrentTrack(null);
document.getElementById('track-info-panel').style.display = 'none';
if (typeof Elevation !== 'undefined') Elevation.clear();
}
} else {
MapView.addTrack(entry.data, id);
MapView.fitTrack(id);
MapView.setCurrentTrack(id);
entry.visible = true;
currentId = id;
showTrackInfo(entry.data.meta);
if (typeof Elevation !== 'undefined') {
const pts = MapView.getTrackPoints(id);
if (pts) Elevation.setTrack(pts, entry.data.meta);
}
}
renderList();
}
function removeTrack(id) {
if (tracks[id]?.visible) MapView.removeTrack(id);
if (currentId === id) {
currentId = null;
MapView.setCurrentTrack(null);
document.getElementById('track-info-panel').style.display = 'none';
if (typeof Elevation !== 'undefined') Elevation.clear();
}
delete tracks[id];
renderList();
}
// ===== Rendering =====
function renderList() {
const list = document.getElementById('browser-list');
const ids = Object.keys(tracks);
if (ids.length === 0) {
list.innerHTML = '
Open a GPX file or drop it onto the map.
';
return;
}
let html = '';
for (const id of ids) {
const { data, visible } = tracks[id];
const meta = data.meta;
const dist = meta.totalDistance ? formatDistance(meta.totalDistance) : '';
html += `