From 87c710bf4afd7ca64c2124dae1226ee7977eb5da Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Fri, 24 Jul 2026 19:13:49 +0700 Subject: [PATCH] Quick Snap: use native camera/gallery input instead of custom camera MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The custom in-app CameraCapture failed on the native APK ("Could not open the camera") due to Capacitor camera permission plumbing, and a single photo is all a spot snap needs. Replace the Quick Snap flow on the map with a hidden native file input (accept="image/*" capture="environment"): one tap opens the OS camera/gallery, the chosen photo feeds the existing upload → create-spot flow unchanged. Works identically on web and native, no plugin/permission fragility. Removes the CameraCapture usage + import from MapPage (component still used by CreateSpotPage). Co-authored-by: shakespeare.diy --- src/pages/MapPage.tsx | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/pages/MapPage.tsx b/src/pages/MapPage.tsx index 06db5e1..7bb8c85 100644 --- a/src/pages/MapPage.tsx +++ b/src/pages/MapPage.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo, useEffect, lazy, Suspense } from 'react'; +import { useState, useMemo, useEffect, useRef, lazy, Suspense } from 'react'; import { useSeoMeta } from '@unhead/react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { Layout } from '@/components/Layout'; @@ -77,7 +77,6 @@ import { Calendar, MessageCircle, } from 'lucide-react'; -import { CameraCapture } from '@/components/CameraCapture'; import { SpotChat } from '@/components/SpotChat'; import { useUploadFile } from '@/hooks/useUploadFile'; import { useToast } from '@/hooks/useToast'; @@ -605,8 +604,11 @@ export default function MapPage() { // Mobile layers popover const [layersOpen, setLayersOpen] = useState(false); - // Quick camera capture - const [showQuickCamera, setShowQuickCamera] = useState(false); + // Quick Snap — uses the native OS camera/gallery picker via a file input. + // This is more robust than a custom in-app camera (no Capacitor camera + // permission plumbing) and works identically on web and native. A single + // photo is all a spot snap needs. + const quickSnapInputRef = useRef(null); const { mutateAsync: uploadFile, isPending: isUploadingQuickPhoto } = useUploadFile(); const { toast } = useToast(); @@ -760,13 +762,20 @@ export default function MapPage() { navigate(`/create-spot?lat=${lat.toFixed(6)}&lng=${lng.toFixed(6)}`); }; + // Native file-input change → hand the chosen photo to the upload flow. + const handleQuickSnapInput = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + // Reset the input so picking the same file again still fires onChange. + e.target.value = ''; + if (file) handleQuickCameraCapture(file); + }; + // Handle quick camera capture - upload and navigate to create spot const handleQuickCameraCapture = async (file: File) => { try { const tags = await uploadFile(file); const url = tags[0]?.[1]; if (url) { - setShowQuickCamera(false); // Store the captured image URL in sessionStorage for the create spot page sessionStorage.setItem('quickCaptureImage', url); // Get current location and navigate to create spot @@ -1700,9 +1709,9 @@ export default function MapPage() { ))} - {/* Quick Snap */} + {/* Quick Snap — opens the native camera/gallery picker */}