# Zoom Button Debug Guide ## Problem Zoom button code exists in `CameraView.tsx` (lines 136-154) but only renders when `hasZoom={true}`. Button not appearing indicates `hasZoom` is `false`. ## Root Cause Investigation The zoom detection logic is in `Scanner.tsx` lines 77-83: ```typescript const video = document.querySelector(`#${scannerId} video`) as HTMLVideoElement; const track = (video?.srcObject as MediaStream)?.getVideoTracks()[0]; const caps = track?.getCapabilities() as any; if (track && caps?.zoom) { setHasZoom(true); setMaxZoom(caps.zoom.max || 3); } ``` **Why it might fail:** 1. `video` element not found in the DOM yet 2. `MediaStream` not attached to video (srcObject is null/undefined) 3. Video track not initialized (getVideoTracks() returns empty array) 4. `getCapabilities()` returns empty object or doesn't expose zoom 5. Camera hardware doesn't support zoom capability ## Debug Logging Added Added comprehensive console logging at Scanner.tsx lines 80-97: ```typescript console.log('[Zoom Detection Debug]', { videoFound: !!video, trackFound: !!track, trackState: track?.readyState, capabilitiesExists: !!caps, zoomCapability: caps?.zoom, zoomMax: caps?.zoom?.max, allCapabilities: Object.keys(caps || {}), }); ``` ## How to Diagnose ### Step 1: Start the app ```bash cd /data/programare_AI/tfm_ainventory source backend/venv/bin/activate python -m uvicorn backend.main:app --port 8916 & cd frontend NEXT_PUBLIC_API_URL=http://localhost:8916 npm run dev -- --port 8917 & ``` ### Step 2: Open browser and navigate to Scanner - Go to `http://localhost:8917` - Navigate to the Scanner page - Allow camera permissions ### Step 3: Check browser console - Open DevTools (F12) - Go to Console tab - Look for `[Zoom Detection Debug]` log - If SUCCESS: see `[Zoom Detection SUCCESS]` message - If FAILED: see `[Zoom Detection FAILED]` message ### Step 4: Interpret Results **If you see:** ``` [Zoom Detection Debug] { videoFound: true, trackFound: true, trackState: "live", capabilitiesExists: true, zoomCapability: {max: 8, min: 1, step: 1}, zoomMax: 8, allCapabilities: ["width", "height", "aspectRatio", "zoom", ...] } [Zoom Detection SUCCESS] - hasZoom set to true, maxZoom: 8 ``` ✅ **Zoom is supported!** Button should appear. If it doesn't, issue is elsewhere. **If you see:** ``` [Zoom Detection Debug] { videoFound: true, trackFound: true, trackState: "live", capabilitiesExists: true, zoomCapability: undefined, zoomMax: undefined, allCapabilities: ["width", "height", "aspectRatio", ...] } [Zoom Detection FAILED] - Camera does not support zoom capability ``` ❌ **Zoom not supported!** This is expected behavior - button correctly hidden. **If you see:** ``` [Zoom Detection Debug] { videoFound: false, trackFound: false, capabilitiesExists: false, ... } ``` ⚠️ **Media not initialized!** Camera permission likely denied or HTML5-QRCode not ready. ## Next Steps Based on Findings ### If zoom IS supported but button still not appearing: 1. Check `CameraView.tsx` prop passing - is `hasZoom` being passed as `true`? 2. Add debug log in CameraView to verify props: `console.log('CameraView props:', {hasZoom})` 3. Check for CSS issues - button might be rendered but invisible ### If zoom NOT supported: 1. Try different browser/device - some don't expose zoom via API 2. Check browser console for permission errors 3. Try HTTPS instead of HTTP (some APIs restricted to secure context) 4. Test on mobile device - zoom support varies ### Browser compatibility: - **Chrome/Chromium:** Generally supports zoom (most reliable) - **Firefox:** Limited zoom support via `applyConstraints()` - **Safari:** Limited or no zoom support - **Mobile browsers:** Varies significantly by platform and device ## Implementation Details ### Camera initialization flow: 1. `Scanner.tsx` useEffect starts `html5-qrcode` 2. After `start()` completes, video element is in DOM 3. Query video element and get MediaStream track 4. Call `track.getCapabilities()` to check zoom support 5. If zoom available, enable button; if not, hide button ### Zoom control (lines 219-226): ```typescript const handleZoomChange = async (nextZoom: number) => { const video = document.querySelector(`#${scannerId} video`) as HTMLVideoElement; const track = (video?.srcObject as MediaStream)?.getVideoTracks()[0]; if (track) { await track.applyConstraints({ advanced: [{ zoom: nextZoom }] as any }); setZoom(nextZoom); } }; ``` ### Zoom button logic (lines 139-143): ```typescript let nextZoom = 1; if (zoom === 1) nextZoom = Math.min(2, maxZoom); else if (zoom < maxZoom / 2) nextZoom = Math.floor(maxZoom / 2); else if (zoom < maxZoom) nextZoom = maxZoom; else nextZoom = 1; ``` Cycles: 1x → 2x → (max/2) → max → 1x ## Files Modified - `frontend/components/Scanner.tsx` — Added debug logging (commit: 2c711551) ## Commit ``` 2c711551 debug: add zoom capability detection logging to Scanner.tsx ```