Fix geolocation on iOS Safari: explicit button + error feedback

Replace silent on-load getCurrentPosition with an opt-in button on
step 1. iOS Safari requires a user gesture for the permission prompt
to appear; calling it on page load suppresses the dialog. The button
triggers the request on tap, shows "Getting location…" while waiting,
and surfaces permission-denied / timeout errors with clear messages.

https://claude.ai/code/session_015myTTMs6yDsAGarATe5ePZ
This commit is contained in:
Claude 2026-03-18 20:16:16 +00:00
parent 1b52caef65
commit 89f60e894b
No known key found for this signature in database

View file

@ -158,11 +158,27 @@
<script> <script>
let gpsCoords = null; let gpsCoords = null;
// Request GPS immediately so it's ready when we need it function getLocation() {
if (navigator.geolocation) { const el = document.getElementById('loc-status');
if (!navigator.geolocation) {
el.textContent = 'Location not supported by this browser.';
return;
}
el.innerHTML = '<span style="color:#888">Getting location…</span>';
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
pos => { gpsCoords = { lat: pos.coords.latitude, lon: pos.coords.longitude }; }, pos => {
() => {} gpsCoords = { lat: pos.coords.latitude, lon: pos.coords.longitude };
el.innerHTML = '<span style="color:#388e3c">📍 Location captured</span>';
},
err => {
const msgs = {
1: 'Permission denied — allow location in Safari settings.',
2: 'Position unavailable.',
3: 'Location request timed out.',
};
el.innerHTML = `<span style="color:#e53e3e">${msgs[err.code] || err.message}</span>`;
},
{ timeout: 15000 }
); );
} }
@ -188,10 +204,14 @@
3: 'End of ride 2', 3: 'End of ride 2',
}; };
dots(n, n - 1); dots(n, n - 1);
const locBlock = n === 1 ? `
<button class="btn btn-gray" style="margin-bottom:10px" onclick="getLocation()">📍 Share location (optional)</button>
<div id="loc-status" style="font-size:0.85rem;text-align:center;min-height:1.2em;margin-bottom:6px"></div>` : '';
render(` render(`
<div class="step-label">Step ${n} of 3</div> <div class="step-label">Step ${n} of 3</div>
<div class="step-title">${labels[n]}</div> <div class="step-title">${labels[n]}</div>
<div class="info-box">Point your camera at the odometer and take a photo.</div> <div class="info-box">Point your camera at the odometer and take a photo.</div>
${locBlock}
<label class="cam-btn" for="img"> <label class="cam-btn" for="img">
📸 Open camera 📸 Open camera
<input type="file" id="img" accept="image/*" capture="environment" <input type="file" id="img" accept="image/*" capture="environment"
@ -313,12 +333,6 @@
async function startOver() { async function startOver() {
await fetch('/reset', { method: 'POST' }); await fetch('/reset', { method: 'POST' });
gpsCoords = null; gpsCoords = null;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
pos => { gpsCoords = { lat: pos.coords.latitude, lon: pos.coords.longitude }; },
() => {}
);
}
showStep(1); showStep(1);
} }