diff --git a/public_html/index.html b/public_html/index.html index b2415ea..06e4a35 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -1539,7 +1539,8 @@ async function startCamera() { addMessage('system', 'Face detection active — reactor tracking engaged.'); faceLoopId = setInterval(async () => { - if (!cameraActive || isSpeaking) return; + if (!cameraActive) return; + // Run detection even while speaking — needed for tracking + prevents lastFaceSeen staling out try { const detection = await faceapi.detectSingleFace( document.getElementById('faceVideo'), @@ -1548,25 +1549,30 @@ async function startCamera() { const now = Date.now(); if (detection) { lastFaceSeen = now; - const {x, y, width, height} = detection.box; - const ratio = (width * height) / (320 * 240); + const ratio = (detection.box.width * detection.box.height) / (320 * 240); - // Drive the reactor to follow the face + // Always drive the reactor updateFaceTarget(detection.box, 320, 240); - // Trigger voice if face fills >3% of frame - if (ratio > 0.03 && !voiceMode && now > autoMicCooldown) { + // Only auto-trigger voice when not already speaking/active, cooldown passed + if (ratio > 0.03 && !voiceMode && !isSpeaking && now > autoMicCooldown) { autoMicCooldown = now + 9000; document.getElementById('cameraBtn').classList.add('cam-sensing'); enterVoiceMode(); } } else { - clearFaceTarget(); - // No face — exit voice mode if face gone >3s - if (voiceMode && now - lastFaceSeen > 3000) { + // While JARVIS is speaking, keep lastFaceSeen fresh so the exit timer doesn't tick down + if (isSpeaking) { lastFaceSeen = now; } + else { clearFaceTarget(); } + + document.getElementById('cameraBtn').classList.remove('cam-sensing'); + + // Exit voice mode only if: face gone >12s AND no command in that same window AND not speaking + const noFaceMs = now - lastFaceSeen; + const noCommandMs = now - (voiceLastCmd || 0); + if (voiceMode && !isSpeaking && noFaceMs > 12000 && noCommandMs > 12000) { exitVoiceMode(); } - document.getElementById('cameraBtn').classList.remove('cam-sensing'); } } catch(_) {} }, 600);