64 lines
3.0 KiB
JavaScript
64 lines
3.0 KiB
JavaScript
/* DONA_V7_AUTO_CLOSE : cinq secondes après FIN audio, pas la fin LLM.
|
|
Les demandes écrites silencieuses gardent le délai de 60s. */
|
|
(() => {
|
|
'use strict';
|
|
if(window.__donaReplyAutoCloseV7) return;
|
|
window.__donaReplyAutoCloseV7=true;
|
|
let timer=0,mode='idle',serial=0,hasSpeech=false,ttsFinished=false;
|
|
const main=()=>document.getElementById('alfredMainV1');
|
|
const focused=()=>main()?.classList.contains('is-focused');
|
|
const textResponse=()=>!document.getElementById('content')?.classList.contains('alfred-view');
|
|
const clear=()=>{if(timer)clearTimeout(timer);timer=0;};
|
|
const modal=()=>document.querySelector('dialog[open], [role="dialog"][aria-modal="true"],.dona-spotify-overlay:not([hidden]),.dona-face-panel:not([hidden])');
|
|
const schedule=ms=>{
|
|
clear();const mine=serial;
|
|
if(!focused()||!textResponse()||(mode==='speaking'&&!ttsFinished)||mode==='thinking'||mode==='listening')return;
|
|
timer=setTimeout(()=>{
|
|
timer=0;
|
|
if(mine!==serial||!focused()||!textResponse()||(mode==='speaking'&&!ttsFinished)||mode==='thinking'||mode==='listening')return;
|
|
if(modal()){schedule(1500);return;}
|
|
document.getElementById('avBack')?.click();
|
|
},ms);
|
|
};
|
|
const startInteraction=()=>{serial++;clear();ttsFinished=false;hasSpeech=false;};
|
|
const socket=window.alfredSocket;
|
|
socket?.on('alfred_state',data=>{
|
|
const next=String(data?.mode||'idle').toLowerCase();
|
|
if((next==='thinking'||next==='listening'||next==='speaking') && mode!==next){
|
|
if(next==='thinking'||next==='listening')startInteraction();
|
|
clear();
|
|
}
|
|
if(next==='speaking')hasSpeech=true;
|
|
mode=next;
|
|
if(next==='idle'&&focused()&&!timer){
|
|
// Fin audio: on_end a déjà eu lieu ou l'événement peut arriver un peu après idle.
|
|
if(ttsFinished)schedule(5000);
|
|
else if(!hasSpeech)schedule(60000);
|
|
}
|
|
});
|
|
socket?.on('alfred_tts_finished',()=>{
|
|
ttsFinished=true;hasSpeech=true;
|
|
// Piper est terminé ; si le mode conversation reste actif, une nouvelle demande annule le délai.
|
|
if(focused() && mode!=='thinking' && mode!=='listening')schedule(5000);
|
|
});
|
|
socket?.on('alfred_render',data=>{
|
|
if(data?.type==='home'){clear();serial++;return;}
|
|
if(focused() && !hasSpeech && mode==='idle')schedule(60000);
|
|
});
|
|
const onFocused=()=>{
|
|
if(!focused()){clear();serial++;return;}
|
|
if(mode==='idle'&&!hasSpeech)schedule(60000);
|
|
};
|
|
const init=()=>{
|
|
if(!main())return;
|
|
new MutationObserver(onFocused).observe(main(),{attributes:true,attributeFilter:['class']});
|
|
document.addEventListener('pointerdown',e=>{
|
|
// L'utilisateur explore la carte : repousser la fermeture sans l'empêcher indéfiniment.
|
|
if(focused()&&e.target?.closest('#stage'))schedule(ttsFinished?5000:60000);
|
|
},{passive:true});
|
|
document.addEventListener('visibilitychange',()=>{if(document.hidden)clear();else if(focused()&&mode==='idle')schedule(ttsFinished?5000:60000);});
|
|
onFocused();
|
|
};
|
|
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});else init();
|
|
})();
|