gallery upload: GPS fallback + auto-lookup

- GPS: when EXIF stripped by mobile browser, falls back to
  navigator.geolocation.getCurrentPosition() for device location
- OCR result now populates scanMachineId hidden field so Create works
- createFromScanPhoto also checks AppState.gpsLat as fallback
- Gallery OCR now auto-lookups via handleBarcode() — routes to confirm
  card (existing asset) or new asset form (not found)
- Manual entry button also calls handleBarcode() after prompt
This commit is contained in:
2026-05-21 14:09:14 -04:00
parent 7331b4e1aa
commit d55cc4aa44
+31 -4
View File
@@ -2621,16 +2621,19 @@
try { try {
const ocrData = await ocrImageClient(file); const ocrData = await ocrImageClient(file);
if (ocrData && ocrData.machine_id) { if (ocrData && ocrData.machine_id) {
document.getElementById('scanMachineId').value = ocrData.machine_id;
if (ocrEl) ocrEl.innerHTML = `✅ Machine ID: <strong>${esc(ocrData.machine_id)}</strong>` + if (ocrEl) ocrEl.innerHTML = `✅ Machine ID: <strong>${esc(ocrData.machine_id)}</strong>` +
(ocrData.confidence === 'low' ? ' ⚠️ Low confidence' : ''); (ocrData.confidence === 'low' ? ' ⚠️ Low confidence' : '');
// Auto-lookup like barcode scan — route to confirm card or new asset form
handleBarcode(ocrData.machine_id);
} else { } else {
if (ocrEl) ocrEl.innerHTML = '❌ No machine ID detected. <button class="btn btn-outline btn-sm" onclick="document.getElementById(\'scanMachineId\').value=prompt(\'Enter machine ID:\')">Enter manually</button>'; if (ocrEl) ocrEl.innerHTML = '❌ No machine ID detected. <button class="btn btn-outline btn-sm" onclick="document.getElementById(\'scanMachineId\').value=prompt(\'Enter machine ID:\');handleBarcode(document.getElementById(\'scanMachineId\').value)">Enter manually</button>';
} }
} catch (ocrErr) { } catch (ocrErr) {
if (ocrEl) ocrEl.textContent = '❌ OCR failed: ' + ocrErr.message; if (ocrEl) ocrEl.textContent = '❌ OCR failed: ' + ocrErr.message;
} }
// Extract GPS from EXIF // Extract GPS from EXIF — fall back to device GPS if stripped
const gpsEl = document.getElementById('scanGpsResult'); const gpsEl = document.getElementById('scanGpsResult');
try { try {
const gps = await extractGpsFromPhoto(file); const gps = await extractGpsFromPhoto(file);
@@ -2638,13 +2641,34 @@
pickedPhotoGps = gps; pickedPhotoGps = gps;
if (gpsEl) { if (gpsEl) {
gpsEl.style.display = 'block'; gpsEl.style.display = 'block';
gpsEl.innerHTML = `📍 GPS: ${gps.lat.toFixed(6)}, ${gps.lng.toFixed(6)}`; gpsEl.innerHTML = `📍 GPS: ${gps.lat.toFixed(6)}, ${gps.lng.toFixed(6)} (from photo)`;
} }
} else { } else {
// EXIF GPS stripped by browser — try device GPS
if (gpsEl) { if (gpsEl) {
gpsEl.innerHTML = '📍 No GPS in photo — trying device location...';
gpsEl.style.display = 'block'; gpsEl.style.display = 'block';
gpsEl.innerHTML = '📍 No GPS data in photo';
} }
navigator.geolocation.getCurrentPosition(
pos => {
const lat = pos.coords.latitude;
const lng = pos.coords.longitude;
const acc = pos.coords.accuracy;
pickedPhotoGps = { lat, lng, accuracy: acc };
AppState.gpsLat = lat;
AppState.gpsLng = lng;
AppState.gpsAcc = acc;
if (gpsEl) {
gpsEl.innerHTML = `📍 GPS: ${lat.toFixed(6)}, ${lng.toFixed(6)} (from device)`;
}
},
err => {
if (gpsEl) {
gpsEl.innerHTML = `📍 No GPS — ${err.message}. Enter manually after creating.`;
}
},
{ enableHighAccuracy: true, timeout: 10000 }
);
} }
} catch (gpsErr) { } catch (gpsErr) {
if (gpsEl) { if (gpsEl) {
@@ -2667,6 +2691,9 @@
if (pickedPhotoGps) { if (pickedPhotoGps) {
payload.latitude = pickedPhotoGps.lat; payload.latitude = pickedPhotoGps.lat;
payload.longitude = pickedPhotoGps.lng; payload.longitude = pickedPhotoGps.lng;
} else if (AppState.gpsLat) {
payload.latitude = AppState.gpsLat;
payload.longitude = AppState.gpsLng;
} }
api('/api/connect-label', { api('/api/connect-label', {