You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.0 KiB
131 lines
4.0 KiB
/* =======================================================================
|
|
File: static/js/log_view.js
|
|
Purpose:
|
|
High-performance rolling log viewer
|
|
- efficient delta polling
|
|
- append-only mode (no DOM reset)
|
|
- rolling limit (prevents memory freeze)
|
|
- supports both global logs and per-book logs
|
|
======================================================================= */
|
|
|
|
console.log(">>> log_view.js LOADING…");
|
|
|
|
/* ---------------------------------------------------------
|
|
Global log viewer state
|
|
--------------------------------------------------------- */
|
|
let LOG_FILTER = "ALL";
|
|
let LAST_LOG_INDEX = -1; // delta offset
|
|
const MAX_LOG_LINES = 600;
|
|
|
|
/* ---------------------------------------------------------
|
|
Apply filter on existing log lines
|
|
--------------------------------------------------------- */
|
|
function applyLogFilter() {
|
|
const lines = $$(".log-line");
|
|
lines.forEach((line) => {
|
|
const text = line.innerText;
|
|
const show = LOG_FILTER === "ALL" || (text && text.includes(LOG_FILTER));
|
|
line.style.display = show ? "block" : "none";
|
|
});
|
|
}
|
|
|
|
/* ---------------------------------------------------------
|
|
DOM Ready — bind clear/filter
|
|
--------------------------------------------------------- */
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
console.log(">>> log_view.js DOMContentLoaded");
|
|
|
|
const clearBtn = $("#log-clear");
|
|
const output = $("#log-output");
|
|
|
|
if (!output) {
|
|
console.log(">>> log_view.js: No #log-output → viewer disabled");
|
|
return;
|
|
}
|
|
|
|
if (clearBtn) {
|
|
clearBtn.addEventListener("click", () => {
|
|
console.log(">>> log_view.js: Clear log viewer");
|
|
output.innerHTML = "";
|
|
LAST_LOG_INDEX = -1;
|
|
});
|
|
}
|
|
});
|
|
|
|
/* ---------------------------------------------------------
|
|
Append ONE line
|
|
--------------------------------------------------------- */
|
|
function rollingAppend(lineText) {
|
|
const output = $("#log-output");
|
|
if (!output) return;
|
|
|
|
const div = document.createElement("div");
|
|
div.classList.add("log-line");
|
|
|
|
// Type detection
|
|
if (lineText.includes("[DL]") || lineText.includes("[DOWNLOAD]"))
|
|
div.classList.add("dl");
|
|
else if (lineText.includes("[PARSE]")) div.classList.add("parse");
|
|
else if (lineText.includes("[SAVE]")) div.classList.add("save");
|
|
else if (lineText.includes("[AUDIO]")) div.classList.add("audio");
|
|
else if (lineText.includes("[CTRL]")) div.classList.add("ctrl");
|
|
else if (lineText.includes("[ERROR]")) div.classList.add("error");
|
|
else div.classList.add("default");
|
|
|
|
div.textContent = lineText;
|
|
output.appendChild(div);
|
|
|
|
// Rolling limit
|
|
while (output.childNodes.length > MAX_LOG_LINES) {
|
|
output.removeChild(output.firstChild);
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------
|
|
Primary entry: updateLogs()
|
|
Accepts:
|
|
{ logs:[...], last:N }
|
|
OR legacy:
|
|
{ lines:[...], last:N }
|
|
--------------------------------------------------------- */
|
|
function updateLogs(packet) {
|
|
const output = $("#log-output");
|
|
if (!output || !packet) return;
|
|
|
|
let lines = packet.logs || packet.lines || [];
|
|
if (!Array.isArray(lines)) return;
|
|
|
|
lines.forEach((line) => rollingAppend(line));
|
|
|
|
// Correct unified delta index handling
|
|
if (packet.last !== undefined) {
|
|
LAST_LOG_INDEX = packet.last;
|
|
}
|
|
|
|
applyLogFilter();
|
|
autoScroll(output);
|
|
}
|
|
|
|
/* ---------------------------------------------------------
|
|
Delta polling — global logs ONLY
|
|
(dashboard.js overrides logs per-book)
|
|
--------------------------------------------------------- */
|
|
function pollLogs() {
|
|
fetch(`/logs?last_index=${LAST_LOG_INDEX}`)
|
|
.then((r) => r.json())
|
|
.then((data) => {
|
|
const lines = data.lines || [];
|
|
if (lines.length > 0) {
|
|
lines.forEach((line) => rollingAppend(line));
|
|
LAST_LOG_INDEX = data.last;
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.warn(">>> log_view.js pollLogs() error:", err);
|
|
});
|
|
}
|
|
|
|
setInterval(pollLogs, 2800);
|
|
|
|
console.log(">>> log_view.js LOADED");
|