← back to Dw Photo Capture
public/caps.html
53 lines
<!doctype html><html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>DW camera capability probe</title>
<style>
body{margin:0;background:#0b0a08;color:#eee;font:15px/1.5 -apple-system,system-ui,sans-serif;padding:18px}
h1{font-size:18px;margin:0 0 4px}.sub{color:#9a917d;font-size:13px;margin-bottom:14px}
#v{width:100%;border-radius:12px;background:#000;margin-bottom:12px}
.row{display:flex;justify-content:space-between;gap:10px;padding:9px 0;border-bottom:1px solid #ffffff14;font-size:14px}
.k{color:#b7ad98}.y{color:#2bd06a;font-weight:700}.n{color:#ff6a6a;font-weight:700}
button{width:100%;padding:14px;margin-top:14px;border:none;border-radius:12px;background:#2bd06a;color:#032;font-size:16px;font-weight:700}
#done{color:#2bd06a;text-align:center;margin-top:12px;font-weight:700;display:none}
</style></head><body>
<h1>DW camera probe</h1>
<div class="sub">Point the back camera at anything, then tap “Send to Claude”. This tells us if your device can measure size by moving the phone (no card).</div>
<video id="v" autoplay playsinline muted></video>
<div id="out"></div>
<button id="send">Send to Claude</button>
<div id="done">✓ Sent — tell Claude “probe done”.</div>
<script>
const $=s=>document.querySelector(s); let CAPS={};
function row(k,ok,val){ return `<div class="row"><span class="k">${k}</span><span class="${ok?'y':'n'}">${val}</span></div>`; }
(async()=>{
const rep={ua:navigator.userAgent, motion:typeof DeviceMotionEvent!=='undefined',
motionPerm:(typeof DeviceMotionEvent!=='undefined' && typeof DeviceMotionEvent.requestPermission==='function')};
try{
if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia){
const chrome=/CriOS|FxiOS|EdgiOS/.test(navigator.userAgent);
throw new Error(chrome?'This is Chrome/other app — iOS only allows the camera in SAFARI. Open in Safari.':'camera API unavailable (open over https in Safari)');
}
const st=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:'environment'}}});
$('#v').srcObject=st; const tr=st.getVideoTracks()[0];
const caps=tr.getCapabilities?tr.getCapabilities():{}, set=tr.getSettings?tr.getSettings():{};
rep.resolution=(set.width||'?')+'x'+(set.height||'?');
rep.zoom=caps.zoom?JSON.stringify(caps.zoom):null;
rep.focusDistance=caps.focusDistance?JSON.stringify(caps.focusDistance):null;
rep.focusDistanceNow=(set.focusDistance!==undefined)?set.focusDistance:null;
rep.focusMode=caps.focusMode?JSON.stringify(caps.focusMode):null;
rep.capsKeys=Object.keys(caps);
}catch(e){ rep.cameraErr=e.message; }
CAPS=rep;
$('#out').innerHTML =
row('Camera', !rep.cameraErr, rep.cameraErr?('ERR '+rep.cameraErr):(rep.resolution||'ok'))+
row('Focus distance (→ card-free!)', !!rep.focusDistance, rep.focusDistance?('YES '+rep.focusDistance):'no')+
row('Live focus distance', rep.focusDistanceNow!=null, rep.focusDistanceNow!=null?String(rep.focusDistanceNow):'no')+
row('Zoom control', !!rep.zoom, rep.zoom?('yes '+rep.zoom):'no')+
row('Motion (parallax fallback)', rep.motion, rep.motion?(rep.motionPerm?'yes (needs tap)':'yes'):'no');
})();
$('#send').addEventListener('click',async()=>{
try{ await fetch('/api/caps',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(CAPS)}); }catch(e){}
$('#done').style.display='block'; $('#send').style.display='none';
});
</script></body></html>