gallery: split Take Photo vs Pick from Gallery inputs

- Two dedicated <input> elements: cameraInput (capture=environment) for
  direct camera, galleryInput (no capture) for gallery picker
- Both wired to handlePickedPhoto() via a shared wireInput helper
- refreshGPS() fires on button click (before picker opens) for a fresh
  high-accuracy GPS fix — no maximumAge, so it pulls current location
  instead of relying on cached values from page-load initGPS()
- Workaround for browser EXIF GPS stripping: camera captures may preserve
  EXIF GPS, gallery picks fall through to device geolocation API
This commit is contained in:
2026-05-21 15:29:03 -04:00
parent 09d83da4e2
commit e16f2ec90f
+36 -11
View File
@@ -1213,8 +1213,9 @@
TAB: ADD ASSET (Barcode / OCR / Manual) TAB: ADD ASSET (Barcode / OCR / Manual)
═══════════════════════════════════════════════════════════════════════ --> ═══════════════════════════════════════════════════════════════════════ -->
<div id="tabAddAsset" class="tab-panel active"> <div id="tabAddAsset" class="tab-panel active">
<!-- Hidden photo picker input --> <!-- Hidden photo inputs: dedicated camera + gallery (EXIF stripping workaround) -->
<input type="file" id="photoPicker" accept="image/*" capture="environment" style="display:none;"> <input type="file" id="cameraInput" accept="image/*" capture="environment" style="display:none;">
<input type="file" id="galleryInput" accept="image/*" style="display:none;">
<!-- Mode Toggles --> <!-- Mode Toggles -->
<div class="mode-toggles"> <div class="mode-toggles">
<button class="mode-toggle active" data-mode="barcode" onclick="setAddAssetMode('barcode')">📷 Scan</button> <button class="mode-toggle active" data-mode="barcode" onclick="setAddAssetMode('barcode')">📷 Scan</button>
@@ -1238,7 +1239,8 @@
<div id="scanStatus" class="status-bar">Point camera at a barcode or sticker</div> <div id="scanStatus" class="status-bar">Point camera at a barcode or sticker</div>
<div id="scanResult" class="scan-result" style="display:none;"></div> <div id="scanResult" class="scan-result" style="display:none;"></div>
<div style="display:flex;gap:6px;margin-top:6px;"> <div style="display:flex;gap:6px;margin-top:6px;">
<button class="btn btn-outline btn-sm" onclick="document.getElementById('photoPicker').click()" style="flex:1;">📱 Pick from Gallery</button> <button class="btn btn-outline btn-sm" onclick="refreshGPS();document.getElementById('cameraInput').click()" style="flex:1;">📸 Take Photo</button>
<button class="btn btn-outline btn-sm" onclick="refreshGPS();document.getElementById('galleryInput').click()" style="flex:1;">📱 Pick from Gallery</button>
</div> </div>
</div> </div>
@@ -2369,6 +2371,25 @@
); );
} }
// Refresh GPS fix on demand (called when user taps Take Photo / Pick from Gallery)
function refreshGPS() {
if (!navigator.geolocation) return;
navigator.geolocation.getCurrentPosition(
pos => {
AppState.gpsLat = pos.coords.latitude;
AppState.gpsLng = pos.coords.longitude;
AppState.gpsAcc = pos.coords.accuracy;
const badge = document.getElementById('gpsBadge');
if (badge) {
badge.className = 'gps-badge ok';
badge.textContent = `📍 ${AppState.gpsLat.toFixed(4)}, ${AppState.gpsLng.toFixed(4)}`;
}
},
() => {}, // silent fail — keep existing fix if user denies
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
);
}
// ========================================================================= // =========================================================================
// TOAST // TOAST
// ========================================================================= // =========================================================================
@@ -2594,16 +2615,20 @@
let pickedPhotoFile = null; let pickedPhotoFile = null;
let pickedPhotoGps = null; // { lat, lng, accuracy } from EXIF let pickedPhotoGps = null; // { lat, lng, accuracy } from EXIF
// Wire the hidden file input // Wire the hidden file inputs (camera + gallery — two paths for EXIF GPS workaround)
(function() { (function() {
const pp = document.getElementById('photoPicker'); function wireInput(id) {
if (pp) { const el = document.getElementById(id);
pp.addEventListener('change', function(e) { if (el) {
if (e.target.files && e.target.files[0]) { el.addEventListener('change', function(e) {
handlePickedPhoto(e.target.files[0]); if (e.target.files && e.target.files[0]) {
} handlePickedPhoto(e.target.files[0]);
}); }
});
}
} }
wireInput('cameraInput');
wireInput('galleryInput');
})(); })();
function handlePickedPhoto(file) { function handlePickedPhoto(file) {