@ -4951,16 +4951,22 @@
let lastTapLocation = null;
// Navigation confirmation dialog handlers
document.getElementById('navConfirmYes').addEventListener('click', () => {
document.getElementById('navConfirmDialog').style.display = 'none';
const el_navConfirmYes = document.getElementById('navConfirmYes');
if (el_navConfirmYes) {
el_navConfirmYes.addEventListener('click', () => {
document.getElementById('navConfirmDialog').style.display = 'none';
}
if (pendingDestination) {
setDestination(pendingDestination.track, pendingDestination.index);
pendingDestination = null;
}
});
document.getElementById('navConfirmNo').addEventListener('click', () => {
document.getElementById('navConfirmDialog').style.display = 'none';
const el_navConfirmNo = document.getElementById('navConfirmNo');
if (el_navConfirmNo) {
el_navConfirmNo.addEventListener('click', () => {
document.getElementById('navConfirmDialog').style.display = 'none';
}
pendingDestination = null;
});
@ -5955,46 +5961,76 @@
}
// Event listeners
document.getElementById('kmlFile').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
const kmlFileEl = document.getElementById('kmlFile');
if (kmlFileEl) {
kmlFileEl.addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
updateStatus('Loading...', 'info');
updateStatus('Loading...', 'info');
const reader = new FileReader();
reader.onload = function(e) {
try {
const count = parseKML(e.target.result);
updateTrackList();
const reader = new FileReader();
reader.onload = function(e) {
try {
const count = parseKML(e.target.result);
updateTrackList();
if (tracks.length > 0) {
const bounds = L.latLngBounds(tracks.flatMap(t => t.coords));
map.fitBounds(bounds, { padding: [20, 20] });
}
if (tracks.length > 0) {
const bounds = L.latLngBounds(tracks.flatMap(t => t.coords));
map.fitBounds(bounds, { padding: [20, 20] });
}
updateStatus(`Loaded ${count} track(s) from ${file.name}`, 'success');
} catch (err) {
updateStatus(`Error: ${err.message}`, 'error');
}
};
reader.readAsText(file);
});
updateStatus(`Loaded ${count} track(s) from ${file.name}`, 'success');
} catch (err) {
updateStatus(`Error: ${err.message}`, 'error');
}
};
reader.readAsText(file);
});
}
document.getElementById('exportBtn').addEventListener('click', exportToKML);
document.getElementById('reloadBtn').addEventListener('click', reloadTracks);
document.getElementById('saveServerBtn').addEventListener('click', saveToServer);
document.getElementById('gpsBtn').addEventListener('click', toggleGPS);
document.getElementById('rotateMapBtn').addEventListener('click', toggleRotateMap);
document.getElementById('autoCenterBtn').addEventListener('click', toggleAutoCenter);
const el_exportBtn = document.getElementById('exportBtn');
if (el_exportBtn) {
el_exportBtn.addEventListener('click', exportToKML);
const reloadBtn = document.getElementById('reloadBtn');
if (reloadBtn) {
reloadBtn.addEventListener('click', reloadTracks);
}
}
const el_saveServerBtn = document.getElementById('saveServerBtn');
if (el_saveServerBtn) {
el_saveServerBtn.addEventListener('click', saveToServer);
const gpsBtn = document.getElementById('gpsBtn');
if (gpsBtn) {
gpsBtn.addEventListener('click', toggleGPS);
}
}
const el_rotateMapBtn = document.getElementById('rotateMapBtn');
if (el_rotateMapBtn) {
el_rotateMapBtn.addEventListener('click', toggleRotateMap);
const autoCenterBtn = document.getElementById('autoCenterBtn');
if (autoCenterBtn) {
autoCenterBtn.addEventListener('click', toggleAutoCenter);
}
}
// Tab switching
document.getElementById('editTab').addEventListener('click', () => switchTab('edit'));
document.getElementById('navTab').addEventListener('click', () => switchTab('navigate'));
document.getElementById('adminTab').addEventListener('click', () => switchTab('admin'));
const el_editTab = document.getElementById('editTab');
if (el_editTab) {
el_editTab.addEventListener('click', () => switchTab('edit'));
const navTab = document.getElementById('navTab');
if (navTab) {
navTab.addEventListener('click', () => switchTab('navigate'));
}
}
const el_adminTab = document.getElementById('adminTab');
if (el_adminTab) {
el_adminTab.addEventListener('click', () => switchTab('admin'));
// Edit overlay close button
setTimeout(() => {
const editCloseBtn = document.getElementById('editCloseBtn');
// Edit overlay close button
setTimeout(() => {
const editCloseBtn = document.getElementById('editCloseBtn');
}
if (editCloseBtn) {
editCloseBtn.addEventListener('click', (e) => {
e.preventDefault();
@ -6035,10 +6071,19 @@
}, 100);
// Password dialog
document.getElementById('passwordSubmit').addEventListener('click', checkPassword);
document.getElementById('passwordCancel').addEventListener('click', hidePasswordDialog);
document.getElementById('passwordInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') checkPassword();
const el_passwordSubmit = document.getElementById('passwordSubmit');
if (el_passwordSubmit) {
el_passwordSubmit.addEventListener('click', checkPassword);
const passwordCancel = document.getElementById('passwordCancel');
if (passwordCancel) {
passwordCancel.addEventListener('click', hidePasswordDialog);
}
}
const el_passwordInput = document.getElementById('passwordInput');
if (el_passwordInput) {
el_passwordInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') checkPassword();
}
});
// Navigation
@ -6087,9 +6132,12 @@
remeshValueDisplay.textContent = remeshSlider.value;
});
document.getElementById('remeshBtn').addEventListener('click', () => {
if (selectedTracks.length === 0) {
updateStatus('Please select tracks to remesh first', 'error');
const el_remeshBtn = document.getElementById('remeshBtn');
if (el_remeshBtn) {
el_remeshBtn.addEventListener('click', () => {
if (selectedTracks.length === 0) {
updateStatus('Please select tracks to remesh first', 'error');
}
return;
}
@ -6107,8 +6155,11 @@
document.getElementById('remeshDialog').style.display = 'flex';
});
document.getElementById('remeshYes').addEventListener('click', () => {
document.getElementById('remeshDialog').style.display = 'none';
const el_remeshYes = document.getElementById('remeshYes');
if (el_remeshYes) {
el_remeshYes.addEventListener('click', () => {
document.getElementById('remeshDialog').style.display = 'none';
}
// Get the spacing value from slider
const spacing = parseInt(remeshSlider.value);
@ -6122,26 +6173,43 @@
clearSelection();
});
document.getElementById('remeshNo').addEventListener('click', () => {
document.getElementById('remeshDialog').style.display = 'none';
const el_remeshNo = document.getElementById('remeshNo');
if (el_remeshNo) {
el_remeshNo.addEventListener('click', () => {
document.getElementById('remeshDialog').style.display = 'none';
}
});
// Preview system
document.getElementById('previewBtn').addEventListener('click', startPreview);
document.getElementById('applyMergeBtn').addEventListener('click', applyMerge);
document.getElementById('cancelPreviewBtn').addEventListener('click', cancelPreview);
const el_previewBtn = document.getElementById('previewBtn');
if (el_previewBtn) {
el_previewBtn.addEventListener('click', startPreview);
const applyMergeBtn = document.getElementById('applyMergeBtn');
if (applyMergeBtn) {
applyMergeBtn.addEventListener('click', applyMerge);
}
}
const el_cancelPreviewBtn = document.getElementById('cancelPreviewBtn');
if (el_cancelPreviewBtn) {
el_cancelPreviewBtn.addEventListener('click', cancelPreview);
// Live slider update during preview
document.getElementById('mergeThreshold').addEventListener('input', (e) => {
document.getElementById('thresholdValue').textContent = e.target.value;
// Live slider update during preview
const mergeThreshold = document.getElementById('mergeThreshold');
if (mergeThreshold) {
mergeThreshold.addEventListener('input', (e) => {
document.getElementById('thresholdValue').textContent = e.target.value;
}
if (previewMode) {
updatePreview(parseInt(e.target.value));
}
});
// Anchor distance slider update
document.getElementById('anchorDistance').addEventListener('input', (e) => {
document.getElementById('anchorValue').textContent = e.target.value;
const el_anchorDistance = document.getElementById('anchorDistance');
if (el_anchorDistance) {
el_anchorDistance.addEventListener('input', (e) => {
document.getElementById('anchorValue').textContent = e.target.value;
}
// If currently dragging, update the affected markers display
if (isDragging & & originalCoords) {
showAffectedRange();
@ -6156,8 +6224,11 @@
});
// Falloff slider update
document.getElementById('reshapeFalloff').addEventListener('input', (e) => {
document.getElementById('falloffValue').textContent = parseFloat(e.target.value).toFixed(1);
const el_reshapeFalloff = document.getElementById('reshapeFalloff');
if (el_reshapeFalloff) {
el_reshapeFalloff.addEventListener('input', (e) => {
document.getElementById('falloffValue').textContent = parseFloat(e.target.value).toFixed(1);
}
// If currently dragging, re-apply with new falloff
if (isDragging & & originalCoords) {
const anchorDist = parseInt(document.getElementById('anchorDistance').value);
@ -6170,8 +6241,11 @@
});
// Smooth brush size slider update
document.getElementById('smoothBrushSize').addEventListener('input', (e) => {
document.getElementById('brushSizeValue').textContent = e.target.value;
const el_smoothBrushSize = document.getElementById('smoothBrushSize');
if (el_smoothBrushSize) {
el_smoothBrushSize.addEventListener('input', (e) => {
document.getElementById('brushSizeValue').textContent = e.target.value;
}
// Update brush circle if currently smoothing
if (isSmoothing & & smoothBrushCircle) {
const brushSize = parseInt(e.target.value);
@ -6180,8 +6254,11 @@
});
// Smooth strength slider update
document.getElementById('smoothStrength').addEventListener('input', (e) => {
document.getElementById('strengthValue').textContent = parseFloat(e.target.value).toFixed(1);
const el_smoothStrength = document.getElementById('smoothStrength');
if (el_smoothStrength) {
el_smoothStrength.addEventListener('input', (e) => {
document.getElementById('strengthValue').textContent = parseFloat(e.target.value).toFixed(1);
}
});
// Register Service Worker for PWA functionality
@ -6405,8 +6482,11 @@
checkPushSubscription();
// Setup resume navigation dialog handlers
document.getElementById('resumeNavYes').addEventListener('click', () => {
document.getElementById('resumeNavDialog').style.display = 'none';
const el_resumeNavYes = document.getElementById('resumeNavYes');
if (el_resumeNavYes) {
el_resumeNavYes.addEventListener('click', () => {
document.getElementById('resumeNavDialog').style.display = 'none';
}
// Restore saved navigation
const savedNav = localStorage.getItem('navMode');
if (savedNav === 'true') {
@ -6415,8 +6495,11 @@
}
});
document.getElementById('resumeNavNo').addEventListener('click', () => {
document.getElementById('resumeNavDialog').style.display = 'none';
const el_resumeNavNo = document.getElementById('resumeNavNo');
if (el_resumeNavNo) {
el_resumeNavNo.addEventListener('click', () => {
document.getElementById('resumeNavDialog').style.display = 'none';
}
localStorage.removeItem('navDestination');
localStorage.removeItem('navMode');
});