Full implementation from spec: ZNC/IRC client with TLS, Ollama LLM backend, per-user SQLite conversation memory, and Flask web admin portal with 7 pages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
// Auto-refresh for logs page
|
|
(function () {
|
|
const checkbox = document.getElementById("auto-refresh");
|
|
if (!checkbox) return;
|
|
|
|
let timer = null;
|
|
|
|
function refresh() {
|
|
fetch("/api/logs")
|
|
.then((r) => r.json())
|
|
.then((data) => {
|
|
const box = document.getElementById("log-box");
|
|
if (!box) return;
|
|
box.innerHTML = data.lines
|
|
.map((l) => `<div class="log-line ${logClass(l)}">${escHtml(l)}</div>`)
|
|
.join("");
|
|
box.scrollTop = box.scrollHeight;
|
|
})
|
|
.catch(() => {});
|
|
}
|
|
|
|
checkbox.addEventListener("change", () => {
|
|
if (checkbox.checked) {
|
|
refresh();
|
|
timer = setInterval(refresh, 3000);
|
|
} else {
|
|
clearInterval(timer);
|
|
timer = null;
|
|
}
|
|
});
|
|
|
|
// Scroll to bottom on load
|
|
const box = document.getElementById("log-box");
|
|
if (box) box.scrollTop = box.scrollHeight;
|
|
|
|
function logClass(line) {
|
|
if (line.includes("IRC IN:")) return "log-irc-in";
|
|
if (line.includes("IRC OUT:")) return "log-irc-out";
|
|
if (line.includes("[LLM]")) return "log-llm";
|
|
if (line.includes("[ERROR]") || line.includes("ERROR")) return "log-error";
|
|
if (line.includes("[CONFIG]")) return "log-config";
|
|
if (line.includes("[MEMORY]")) return "log-memory";
|
|
return "";
|
|
}
|
|
|
|
function escHtml(str) {
|
|
return str
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">");
|
|
}
|
|
})();
|