/* ===================================================================
Gemeinsamer Zugang zur lokalen KI.
Liegt in einer eigenen Datei, weil drei Seiten sie benutzen (Calls,
Start-Check, Report) und die Absicherung sonst dreimal dastuende --
und beim naechsten Mal in zwei davon.
ZWEI REGELN:
1. IST DIE KI AUS, GIBT ES DEN KNOPF NICHT. Ein Knopf, der immer eine
Fehlermeldung bringt, ist schlimmer als gar kein Knopf. Deshalb
fragt jede Seite beim Laden einmal nach und baut ihn nur dann.
2. DIE KI SCHLAEGT VOR, DER MENSCH ENTSCHEIDET. Kein Aufruf hier
speichert etwas. Was uebernommen wird, traegt der Mensch an
derselben Stelle ein wie ohne KI.
=================================================================== */
window.KI = (() => {
'use strict';
let bekannt = null; // null = noch nicht gefragt
/* Einmal pro Seitenaufruf fragen, danach gemerkt. */
async function verfuegbar() {
if (bekannt !== null) return bekannt;
try {
const a = await fetch('/workspace/api/ki/status', { credentials: 'same-origin' });
bekannt = a.ok ? (await a.json()).da === true : false;
} catch { bekannt = false; }
return bekannt;
}
async function frage(pfad, koerper) {
const a = await fetch('/workspace/api/ki/' + pfad, {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(koerper),
});
if (a.status === 401) { location.assign('/workspace/'); throw new Error('abgemeldet'); }
const d = await a.json().catch(() => ({}));
if (!a.ok) throw new Error(sagWas(d.fehler, 'Die KI konnte nicht antworten.'));
return d;
}
/* Baut einen Knopf, der waehrend des Denkens sagt, dass er denkt --
zwoelf Sekunden ohne Rueckmeldung fuehlen sich an wie ein Fehler. */
function knopf(beschriftung, tuWas) {
const b = document.createElement('button');
b.type = 'button';
b.className = 'ki-knopf';
const funke = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
funke.setAttribute('viewBox', '0 0 24 24');
funke.setAttribute('class', 'ki-knopf__funke');
funke.setAttribute('aria-hidden', 'true');
funke.innerHTML = ''
+ '';
const text = document.createElement('span');
text.textContent = beschriftung;
b.append(funke, text);
b.addEventListener('click', async () => {
if (b.disabled) return;
b.disabled = true;
b.dataset.denkt = 'ja';
const vorher = text.textContent;
text.textContent = 'Die KI denkt …';
try {
await tuWas();
} catch (fehler) {
/* Die Meldung gehoert dorthin, wo der Knopf steht -- nicht in
ein Fenster, das den Rest verdeckt. */
const hinweis = document.createElement('span');
hinweis.className = 'ki-fehler';
hinweis.textContent = fehler.message;
b.after(hinweis);
setTimeout(() => hinweis.remove(), 7000);
} finally {
delete b.dataset.denkt;
text.textContent = vorher;
b.disabled = false;
}
});
return b;
}
return { verfuegbar, frage, knopf };
})();