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.
146 lines
4.4 KiB
146 lines
4.4 KiB
/* ============================================================
|
|
File: static/js/bookcard_controller.js
|
|
Purpose:
|
|
Single owner for updating book-card DOM from merged state
|
|
(would_merge_to)
|
|
============================================================ */
|
|
|
|
console.log("[BOOKCARD] controller loaded");
|
|
|
|
/* ============================================================
|
|
ENTRY POINT (called by state_updater.js)
|
|
============================================================ */
|
|
|
|
function updateBookCardsFromState(stateList) {
|
|
console.log("[BOOKCARD] updateBookCardsFromState called");
|
|
|
|
if (!Array.isArray(stateList)) {
|
|
console.warn("[BOOKCARD] Invalid stateList", stateList);
|
|
return;
|
|
}
|
|
|
|
const stateById = {};
|
|
|
|
stateList.forEach((entry) => {
|
|
const merged = entry.would_merge_to;
|
|
if (!merged || merged.book_idx == null) {
|
|
console.warn("[BOOKCARD] entry without merged/book_idx", entry);
|
|
return;
|
|
}
|
|
stateById[String(merged.book_idx)] = merged;
|
|
});
|
|
|
|
document.querySelectorAll(".book-card").forEach((card) => {
|
|
const bookIdx = card.dataset.bookIdx;
|
|
const state = stateById[bookIdx];
|
|
|
|
if (!state) {
|
|
console.debug("[BOOKCARD] No state for book_idx", bookIdx);
|
|
return;
|
|
}
|
|
|
|
console.log("[BOOKCARD] Updating card", bookIdx, state.status);
|
|
updateSingleBookCard(card, state);
|
|
});
|
|
}
|
|
|
|
/* ============================================================
|
|
SINGLE CARD UPDATE
|
|
============================================================ */
|
|
|
|
function updateSingleBookCard(card, state) {
|
|
console.log("[BOOKCARD] updateSingleBookCard", state.book_idx);
|
|
|
|
updateStatus(card, state);
|
|
updateStatusBadge(card, state);
|
|
updateButtons(card, state);
|
|
updateProgress(card, state);
|
|
}
|
|
|
|
/* ============================================================
|
|
STATUS
|
|
============================================================ */
|
|
|
|
function updateStatus(card, state) {
|
|
console.log("[BOOKCARD][STATUS]", state.book_idx, "→", state.status);
|
|
card.className = `book-card ${state.status || ""}`;
|
|
}
|
|
function updateStatusBadge(card, state) {
|
|
const badge = card.querySelector(".status-badge");
|
|
if (!badge) return;
|
|
|
|
const status = (state.status || "").toLowerCase();
|
|
|
|
badge.textContent = status.toUpperCase();
|
|
badge.className = `status-badge status-${status}`;
|
|
badge.title =
|
|
{
|
|
downloading: "Bezig met downloaden",
|
|
audio: "Downloads compleet, audio wordt gegenereerd",
|
|
done: "Alle chapters en audio zijn compleet",
|
|
}[status] || "";
|
|
}
|
|
|
|
/* ============================================================
|
|
BUTTONS
|
|
============================================================ */
|
|
|
|
function updateButtons(card, state) {
|
|
const startBtn = card.querySelector(".icon-start");
|
|
const abortBtn = card.querySelector(".icon-abort");
|
|
|
|
const busy = ["starting", "downloading", "parsing", "audio"];
|
|
|
|
console.log("[BOOKCARD][BUTTONS]", state.book_idx, "status:", state.status);
|
|
|
|
if (startBtn) {
|
|
// startBtn.disabled = busy.includes(state.status);
|
|
}
|
|
|
|
if (abortBtn) {
|
|
abortBtn.disabled = !busy.includes(state.status);
|
|
}
|
|
}
|
|
|
|
/* ============================================================
|
|
PROGRESS (DOWNLOAD + AUDIO)
|
|
============================================================ */
|
|
|
|
function updateProgress(card, s) {
|
|
const total = Number(s.chapters_total || 0);
|
|
|
|
// const downloadDone =
|
|
// Number(s.chapters_download_done || 0) +
|
|
// Number(s.chapters_download_skipped || 0);
|
|
const downloadDone = Number(s.downloaded || 0);
|
|
|
|
const audioDone = Number(s.audio_done || 0) + Number(s.audio_skipped || 0);
|
|
|
|
const downloadPct =
|
|
total > 0 ? Math.min((downloadDone / total) * 100, 100) : 0;
|
|
|
|
const audioPct = total > 0 ? Math.min((audioDone / total) * 100, 100) : 0;
|
|
|
|
console.log("[BOOKCARD][PROGRESS]", s.book_idx, {
|
|
total,
|
|
downloadDone,
|
|
audioDone,
|
|
downloadPct,
|
|
audioPct,
|
|
});
|
|
|
|
/* ---- DOWNLOAD ---- */
|
|
const dlBar = card.querySelector('[data-field="download_pct"]');
|
|
const dlText = card.querySelector('[data-field="download_text"]');
|
|
|
|
if (dlBar) dlBar.style.width = `${downloadPct}%`;
|
|
if (dlText) dlText.textContent = `${downloadDone} / ${total}`;
|
|
|
|
/* ---- AUDIO ---- */
|
|
const auBar = card.querySelector('[data-field="audio_pct"]');
|
|
const auText = card.querySelector('[data-field="audio_text"]');
|
|
|
|
if (auBar) auBar.style.width = `${audioPct}%`;
|
|
if (auText) auText.textContent = `${audioDone} / ${total}`;
|
|
}
|