mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 14:38:12 +02:00
Rebaptise AJEAN en Loki (fork, lignée conservée)
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki) - LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ; units loki-engine / loki-ui ; binaire et aide CLI - updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les binaires AJEAN amont) Conservé à l'identique : le domaine ajean.link (service de tunnel amont), les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et LICENSE (historique et licence de l'amont). go build/vet/test : verts.
This commit is contained in:
157 files changed
+928
-928
No files matched your search
@@ -0,0 +1,85 @@
|
||||
// Pastille d'état d'une section du menu (mode agent, internet, MCP, distant).
|
||||
// `state` : true = actif (pilule pleine), false = inactif (contour), 'warn'/'err'
|
||||
// = état signalé, null = pastille masquée. Un seul endroit décide de leur allure.
|
||||
function setBadge(id, state, text){
|
||||
const el = typeof id==='string' ? document.getElementById(id) : id;
|
||||
if(!el) return;
|
||||
el.className = 'sbadge' + (state===true ? ' on' : (state==='warn' || state==='err') ? ' '+state : '');
|
||||
el.textContent = state===null || state===undefined ? '' : (text||'');
|
||||
}
|
||||
// Ouverture/fermeture des modales. Le display seul apparaissait d'un bloc : on
|
||||
// pose la classe .show une frame APRÈS l'affichage pour que la transition CSS
|
||||
// parte de son état initial (sans ce reflow forcé, le navigateur applique tout
|
||||
// d'un coup et l'animation ne joue pas). À la fermeture on attend la fin de la
|
||||
// transition avant de repasser en display:none.
|
||||
function showModal(id){
|
||||
const el = typeof id==='string' ? document.getElementById(id) : id;
|
||||
if(!el) return;
|
||||
el.style.display='flex';
|
||||
void el.offsetHeight;
|
||||
el.classList.add('show');
|
||||
}
|
||||
function hideModal(id){
|
||||
const el = typeof id==='string' ? document.getElementById(id) : id;
|
||||
if(!el) return;
|
||||
el.classList.remove('show');
|
||||
// Rouverte entre-temps ? On ne la cache surtout pas.
|
||||
setTimeout(()=>{ if(!el.classList.contains('show')) el.style.display='none'; }, 180);
|
||||
}
|
||||
function toast(m){ const t=document.getElementById('toast'); t.textContent=m; t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),1800); }
|
||||
// Modales natives (askConfirm/askPrompt/askAlert) — remplacent confirm()/prompt()/
|
||||
// alert() par de vraies boîtes stylées. Chacune renvoie une Promise : askConfirm →
|
||||
// bool, askPrompt → string|null (null si annulé), askAlert → void. Échap/clic dehors
|
||||
// = annuler ; Entrée = valider (sur prompt aussi).
|
||||
let _askResolver=null, _askKind='confirm', _askCheck=false;
|
||||
// État de la case optionnelle de la DERNIÈRE confirmation (opts.check). Lu par
|
||||
// l'appelant juste après le await — la Promise, elle, ne renvoie que oui/non.
|
||||
function askChecked(){ return _askCheck; }
|
||||
function askResolve(ok){
|
||||
if(!_askResolver) return;
|
||||
const r=_askResolver; _askResolver=null;
|
||||
_askCheck = ok && document.getElementById('ask-check-input').checked;
|
||||
hideModal('ask-modal');
|
||||
document.removeEventListener('keydown', _askKey, true);
|
||||
if(_askKind==='prompt') r(ok ? document.getElementById('ask-input').value : null);
|
||||
else r(ok);
|
||||
}
|
||||
function _askKey(e){
|
||||
if(e.key==='Escape'){ e.preventDefault(); e.stopPropagation(); askResolve(false); }
|
||||
else if(e.key==='Enter'){ e.preventDefault(); e.stopPropagation(); askResolve(true); }
|
||||
}
|
||||
function _openAsk(kind, message, opts){
|
||||
// Compat 2 conventions : (message, opts) [UI loki] ET l'objet unique
|
||||
// {title,msg,yes,no,placeholder} passé par e2e.js sur ajean.link (server.html,
|
||||
// où cette fonction remplace le window.askConfirm du bootstrap boîte noire).
|
||||
if(message && typeof message==='object'){ const o=message; opts={title:o.title, okText:o.yes, cancelText:o.no, placeholder:o.placeholder, default:o.default, danger:o.danger}; message=o.msg||''; }
|
||||
opts=opts||{};
|
||||
// Une modale déjà ouverte ne doit pas être écrasée en silence : son appelant
|
||||
// attend une réponse, et l'écraser laissait sa promesse pendante POUR
|
||||
// TOUJOURS (requête suspendue, bouton figé). On l'annule proprement d'abord.
|
||||
if(_askResolver){ const prev=_askResolver; _askResolver=null; prev(_askKind==='prompt' ? null : false); }
|
||||
_askKind=kind;
|
||||
document.getElementById('ask-title').textContent = opts.title || (kind==='alert'?'Info':kind==='prompt'?'Saisie':'Confirmation');
|
||||
document.getElementById('ask-msg').textContent = message||'';
|
||||
const inp=document.getElementById('ask-input');
|
||||
if(kind==='prompt'){ inp.style.display=''; inp.value=opts.default||''; inp.placeholder=opts.placeholder||''; }
|
||||
else inp.style.display='none';
|
||||
// Case facultative (ex. « supprimer aussi le fichier .gguf »).
|
||||
const chk=document.getElementById('ask-check');
|
||||
chk.style.display = opts.check ? 'inline-flex' : 'none';
|
||||
document.getElementById('ask-check-label').textContent = opts.check || '';
|
||||
document.getElementById('ask-check-input').checked = false;
|
||||
_askCheck=false;
|
||||
const cancel=document.getElementById('ask-cancel'), ok=document.getElementById('ask-ok');
|
||||
cancel.style.display = kind==='alert' ? 'none' : '';
|
||||
cancel.textContent = opts.cancelText || 'Annuler';
|
||||
ok.textContent = opts.okText || (kind==='alert'?'OK':kind==='prompt'?'Valider':'Confirmer');
|
||||
ok.classList.toggle('danger', !!opts.danger);
|
||||
showModal('ask-modal');
|
||||
document.addEventListener('keydown', _askKey, true);
|
||||
setTimeout(()=>{ const f = kind==='prompt'?inp:ok; f.focus(); if(kind==='prompt') inp.select(); }, 30);
|
||||
return new Promise(res=>{ _askResolver=res; });
|
||||
}
|
||||
function askConfirm(message,opts){ return _openAsk('confirm',message,opts); }
|
||||
function askPrompt(message,opts){ return _openAsk('prompt',message,opts); }
|
||||
function askAlert(message,opts){ return _openAsk('alert',message,opts); }
|
||||
Reference in new issue
Block a user