Files
Alfredv2/alfred/app/static/js/dona-files-v9-1.js
T
2026-10-31 11:04:45 +01:00

62 lines
8.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* DONA_FILES_V91 — documents et images, contenu affiché exclusivement avec textContent. */
(()=>{
'use strict';
if(window.DonaFilesV91)return;
const $=id=>document.getElementById(id);
const el=(tag,cls,text)=>{const n=document.createElement(tag);if(cls)n.className=cls;if(text!==undefined)n.textContent=String(text);return n;};
const button=(text,fn,cls='df-button')=>{const b=el('button',cls,text);b.type='button';b.addEventListener('click',fn);return b;};
let active=null, busy=false, previewURL=null;
function status(text){if($('dfStatus'))$('dfStatus').textContent=String(text||'');}
function setBusy(val){busy=val;for(const id of ['dfUpload','dfAnalyze','dfDrop','dfDelete']){const n=$(id);if(n)n.disabled=val;}}
async function postJson(path,data){const response=await fetch(path,{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json','X-Alfred-Request':'1'},body:JSON.stringify(data)});const obj=await response.json().catch(()=>({}));if(!response.ok||obj.ok===false)throw Error(obj.error||'Erreur HTTP '+response.status);return obj;}
function open(){if(!$('donaFilesV91'))init();$('donaFilesV91').hidden=false;document.body.classList.add('df-open');}
function close(){if(busy)return;$('donaFilesV91').hidden=true;document.body.classList.remove('df-open');}
function showAttachment(info,file){active=info;$('dfName').textContent=info.filename+' · '+(Math.round(info.size/1024))+' Ko';$('dfCurrent').hidden=false;$('dfEmpty').hidden=true;$('dfAnswer').textContent='';$('dfQuestion').value=info.kind==='image'?'Que vois-tu sur cette image ?':'Fais un résumé clair de ce document.';
if(previewURL){URL.revokeObjectURL(previewURL);previewURL=null;}const picture=$('dfPreview');picture.hidden=true;picture.removeAttribute('src');
if(info.kind==='image'&&file){previewURL=URL.createObjectURL(file);picture.src=previewURL;picture.hidden=false;}status('Fichier prêt. Tu peux demander une analyse.');}
async function upload(file){if(!file||busy)return;if(file.size>10*1024*1024){status('Taille maximale : 10 Mo.');return;}setBusy(true);status('Téléversement…');try{const form=new FormData();form.append('file',file,file.name);const response=await fetch('/api/dona/files/upload',{method:'POST',credentials:'same-origin',headers:{'X-Alfred-Request':'1'},body:form});const obj=await response.json().catch(()=>({}));if(!response.ok||obj.ok===false)throw Error(obj.error||'Téléversement impossible.');const previous=active;showAttachment(obj,file);if(previous&&previous.id!==obj.id)postJson('/api/dona/files/delete',{id:previous.id}).catch(()=>{});}catch(e){status('Erreur : '+e.message);}finally{setBusy(false);}}
async function analyze(){if(!active||busy){status('Ajoute d’abord un fichier.');return;}const question=String($('dfQuestion').value||'').trim();if(!question){status('Saisis une question.');return;}setBusy(true);status('Hermes analyse le fichier…');$('dfAnswer').textContent='';try{const result=await postJson('/api/dona/files/analyze',{id:active.id,question});$('dfAnswer').textContent=result.answer||'Aucune réponse.';status('Analyse terminée.');}catch(e){status('Erreur : '+e.message);}finally{setBusy(false);}}
async function remove(){if(!active||busy)return;setBusy(true);try{await postJson('/api/dona/files/delete',{id:active.id});active=null;$('dfCurrent').hidden=true;$('dfEmpty').hidden=false;$('dfAnswer').textContent='';$('dfName').textContent='';$('dfInput').value='';status('Fichier effacé.');if(previewURL){URL.revokeObjectURL(previewURL);previewURL=null;}}catch(e){status(e.message);}finally{setBusy(false);}}
function init(){if($('donaFilesV91'))return;const overlay=el('div','df-overlay');overlay.id='donaFilesV91';overlay.hidden=true;const panel=el('section','df-panel');panel.setAttribute('role','dialog');panel.setAttribute('aria-modal','true');panel.setAttribute('aria-label','Analyser un fichier avec Dona');
const head=el('div','df-head');const heading=el('div');heading.append(el('span','df-eyebrow','DONA · PIÈCES JOINTES'),el('h2','','Analyser un document ou une photo'));head.append(heading,button('×',close,'df-close'));panel.append(head);
const help=el('p','df-hint','PDF, Word (.docx), texte, Markdown, JPEG, PNG et WebP · 10 Mo max · Conservation temporaire 30 minutes · Pas d’indexation automatique.');panel.append(help);
const zone=el('div','df-drop');zone.id='dfDrop';zone.setAttribute('role','group');zone.append(el('span','df-upload-icon','📎'),el('strong','','Dépose ton fichier ici ou sélectionne-le'));
const fileInput=el('input','df-file');fileInput.type='file';fileInput.id='dfInput';fileInput.accept='.pdf,.docx,.txt,.md,.jpg,.jpeg,.png,.webp';fileInput.addEventListener('change',()=>{if(fileInput.files?.[0])upload(fileInput.files[0]);});zone.append(fileInput);
const choose=button('Choisir un fichier',()=>fileInput.click(),'df-button df-primary');choose.id='dfUpload';zone.append(choose);zone.addEventListener('dragover',e=>{e.preventDefault();zone.classList.add('df-over');});zone.addEventListener('dragleave',()=>zone.classList.remove('df-over'));zone.addEventListener('drop',e=>{e.preventDefault();zone.classList.remove('df-over');if(e.dataTransfer.files?.[0])upload(e.dataTransfer.files[0]);});panel.append(zone);
const empty=el('p','df-hint','Aucun fichier sélectionné.');empty.id='dfEmpty';panel.append(empty);
const current=el('div','df-current');current.id='dfCurrent';current.hidden=true;const filename=el('div','df-filename');filename.id='dfName';const preview=el('img','df-preview');preview.id='dfPreview';preview.alt='Aperçu du fichier image sélectionné';preview.hidden=true;current.append(filename,preview);const del=button('Supprimer cette pièce jointe',remove,'df-button df-del');del.id='dfDelete';current.append(del);panel.append(current);
const label=el('label','df-label','Que veux-tu savoir ?');label.setAttribute('for','dfQuestion');panel.append(label);const question=el('textarea','df-question');question.id='dfQuestion';question.rows=3;question.maxLength=1200;question.placeholder='Résume ce document, explique les points importants, analyse cette photo…';panel.append(question);
const examples=el('div','df-examples');[['Résumé','Fais un résumé clair de ce document.'],['Points clés','Quels sont les points importants à retenir ?'],['Analyser','Analyse ce fichier et explique-moi ce qu’il contient.'],['Explication','Explique le contenu simplement.']].forEach(([name,q])=>examples.append(button(name,()=>{question.value=q;},'df-chip')));panel.append(examples);
const run=button('Analyser avec Hermes',analyze,'df-button df-primary df-run');run.id='dfAnalyze';panel.append(run);
const msg=el('p','df-status');msg.id='dfStatus';msg.setAttribute('role','status');panel.append(msg);
const result=el('div','df-answer');result.id='dfAnswer';result.setAttribute('aria-live','polite');panel.append(result);
panel.append(el('p','df-hint','Dona garde les fichiers en RAM 30 min ; Hermes peut conserver des traces de session. Le fournisseur IA utilisé dépend de la configuration Hermes. Vérifie-la avant d’envoyer des documents confidentiels. Les PDF scannés sans texte ne sont pas encore pris en charge.'));
overlay.append(panel);document.body.append(overlay);overlay.addEventListener('click',e=>{if(e.target===overlay)close();});document.addEventListener('keydown',e=>{if(e.key==='Escape'&&!overlay.hidden)close();});
// DONA_FILES_V911_COMPOSE : 📎 à droite du bouton d'envoi de « Écrire à Dona ».
// Bouton de type button pour ne jamais soumettre le formulaire lors de son activation.
function mountComposeAttachment(){
const send=$('donaComposeSend');
if(!send || !send.closest('.dona-compose-row'))return false;
let launch=$('dfOpen');
if(!launch){launch=button('📎',open,'df-compose-attach');launch.id='dfOpen';}
launch.type='button';
launch.classList.remove('av-round','df-launch');
launch.classList.add('df-compose-attach');
launch.title='Joindre un fichier à Dona';
launch.setAttribute('aria-label','Joindre un document ou une photo');
send.insertAdjacentElement('afterend',launch);
return true;
}
if(!mountComposeAttachment()){
let count=0;
const timer=setInterval(()=>{
if(mountComposeAttachment() || ++count>100)clearInterval(timer);
},150);
}
const v9quick=document.querySelector('#donaSuiteV9 .dv9-quick');if(v9quick)v9quick.append(button('📎 Analyser un fichier',()=>{if(window.DonaSuiteV9?.close)window.DonaSuiteV9.close();open();},'dv9-chip'));
window.alfredSocket?.on('dona_files_v91_result',result=>{if(result?.answer&&active?.id===result.id){$('dfAnswer').textContent=result.answer;status('Analyse vocale terminée.');}});
}
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});else init();
window.DonaFilesV91={open,close};
})();