book.html: list the trailers already run, because there was no way back
Once you navigated away from a trailer, the only route back to it was the URL. The page offered a way to start work and no way to return to it, which meant every finished run was effectively lost the moment you closed the tab. The list leads with what someone actually wants to know at a glance - is it finished, did every writer survive, has anything been drawn, what has it cost - rather than with an id and a timestamp. A run still working shows what it is doing and keeps polling, so this is also the page you land on to check progress. trailer.html gets a link back, so the two pages are a loop rather than a one-way trip.
This commit is contained in:
parent
fa1992f200
commit
31b3474f8f
1 changed files with 60 additions and 2 deletions
62
book.html
62
book.html
|
|
@ -34,6 +34,18 @@
|
||||||
.wr.on{border-color:var(--accent)}
|
.wr.on{border-color:var(--accent)}
|
||||||
.wr input{margin:0}
|
.wr input{margin:0}
|
||||||
.lead{margin-left:6px;font-size:12px;color:var(--muted)}
|
.lead{margin-left:6px;font-size:12px;color:var(--muted)}
|
||||||
|
.run{display:flex;gap:14px;align-items:center;padding:14px 0;
|
||||||
|
border-top:1px solid var(--line);flex-wrap:wrap}
|
||||||
|
.run:first-child{border-top:0}
|
||||||
|
.run .meta{flex:1;min-width:220px}
|
||||||
|
.run h3{margin:0 0 3px;font-size:16px}
|
||||||
|
.run .sub{color:var(--muted);font-size:13px}
|
||||||
|
.run .who{color:var(--muted);font-size:12px;margin-top:2px}
|
||||||
|
.dot{font-size:12px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);
|
||||||
|
color:var(--muted)}
|
||||||
|
.dot.done{color:var(--accent2);border-color:var(--accent2)}
|
||||||
|
.dot.work{color:var(--accent);border-color:var(--accent)}
|
||||||
|
.dot.bad{color:#e0685f;border-color:#e0685f}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -44,6 +56,13 @@
|
||||||
<p>Upload the manuscript and say what you want the trailer to do. Several models each read the whole book and write their own cinematic trailer — script, cast and shot list. You read them side by side, mark up the shots you want changed, and let them critique each other before one gets filmed.</p>
|
<p>Upload the manuscript and say what you want the trailer to do. Several models each read the whole book and write their own cinematic trailer — script, cast and shot list. You read them side by side, mark up the shots you want changed, and let them critique each other before one gets filmed.</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<section id="runsec" style="display:none">
|
||||||
|
<div class="card">
|
||||||
|
<h2 class="sec">Trailers you have run</h2>
|
||||||
|
<div id="runs"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="msg" id="msg"></div>
|
<div class="msg" id="msg"></div>
|
||||||
|
|
@ -129,7 +148,45 @@ function readFileB64(file) {
|
||||||
navBar("trailer");
|
navBar("trailer");
|
||||||
|
|
||||||
var BOOKS = [], PICKED = null, WRITERS = [], CHOSEN = {}, LEAD = "", EDIT = null;
|
var BOOKS = [], PICKED = null, WRITERS = [], CHOSEN = {}, LEAD = "", EDIT = null;
|
||||||
var pollTimer = null;
|
var pollTimer = null, runTimer = null;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------- runs
|
||||||
|
|
||||||
|
function runHtml(r) {
|
||||||
|
var bits = [];
|
||||||
|
if (r.ready) bits.push(r.ready + " written");
|
||||||
|
if (r.drawn) bits.push(r.drawn + " drawn");
|
||||||
|
if (r.failed) bits.push(r.failed + " failed");
|
||||||
|
if (r.cost_usd) bits.push("$" + Number(r.cost_usd).toFixed(2));
|
||||||
|
if (r.created_at) bits.push(when(r.created_at));
|
||||||
|
|
||||||
|
var cls = r.busy ? "work" : (r.failed && !r.ready ? "bad" : "done");
|
||||||
|
var word = r.busy ? "working" : (r.stage || "");
|
||||||
|
|
||||||
|
return '<div class="run">'
|
||||||
|
+ '<div class="meta"><h3>' + esc(r.book_title || "Untitled") + '</h3>'
|
||||||
|
+ '<div class="sub">' + esc(bits.join(" · ")) + '</div>'
|
||||||
|
+ '<div class="who">' + esc(r.writers || "")
|
||||||
|
+ (r.lead_writer ? ' · lead: ' + esc(r.lead_writer) : '') + '</div>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '<span class="dot ' + cls + '">' + esc(word) + '</span>'
|
||||||
|
+ '<a class="btn" href="/trailer.html?run=' + encodeURIComponent(r.id) + '">'
|
||||||
|
+ (r.busy ? "Watch" : "Review") + '</a>'
|
||||||
|
+ '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRuns() {
|
||||||
|
var r = await api("list_runs", {});
|
||||||
|
if (!r.ok) return;
|
||||||
|
var runs = r.runs || [];
|
||||||
|
document.getElementById("runsec").style.display = runs.length ? "" : "none";
|
||||||
|
document.getElementById("runs").innerHTML = runs.map(runHtml).join("");
|
||||||
|
// A run that is still writing or drawing is worth watching from here, so
|
||||||
|
// this doubles as the progress page.
|
||||||
|
var busy = runs.some(function (x) { return x.busy; });
|
||||||
|
if (busy && !runTimer) runTimer = setInterval(loadRuns, 8000);
|
||||||
|
if (!busy && runTimer) { clearInterval(runTimer); runTimer = null; }
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------- books
|
// ---------------------------------------------------------------- books
|
||||||
|
|
||||||
|
|
@ -207,7 +264,7 @@ function readFileB64(file) {
|
||||||
t.disabled = true;
|
t.disabled = true;
|
||||||
var u = await api("update_book", { book_id: save, title: title, author: author });
|
var u = await api("update_book", { book_id: save, title: title, author: author });
|
||||||
if (!u.ok) { showMsg("msg", u.error || "That did not save."); t.disabled = false; return; }
|
if (!u.ok) { showMsg("msg", u.error || "That did not save."); t.disabled = false; return; }
|
||||||
hideMsg("msg"); EDIT = null; loadBooks();
|
hideMsg("msg"); EDIT = null; loadBooks(); loadRuns();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pick) { PICKED = pick; hideMsg("msg"); paintBooks(); paintQuote(); return; }
|
if (pick) { PICKED = pick; hideMsg("msg"); paintBooks(); paintQuote(); return; }
|
||||||
|
|
@ -344,6 +401,7 @@ function readFileB64(file) {
|
||||||
});
|
});
|
||||||
|
|
||||||
loadBooks();
|
loadBooks();
|
||||||
|
loadRuns();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue