watched: single DONE_RATIO source constant replaces the seven hardcoded 0.95 literals
server/app.py DONE_RATIO is injected into index.html like {{VERSION}}, app.js
reads it as window.DONE_RATIO (fallback = same default). Change the threshold
in exactly one place now.
This commit is contained in:
1 parent
5f7aa010f1
commit
731f44b99c
3 files changed
+22
-9
No files matched your search
+9
-6
@@ -10,6 +10,9 @@ const BASE = (() => {
|
||||
return p.endsWith("/") ? p : p.slice(0, p.lastIndexOf("/") + 1);
|
||||
})();
|
||||
const main = document.getElementById("main");
|
||||
// Watched threshold (fraction of duration) — injected inline by the server
|
||||
// from DONE_RATIO in server/app.py; fallback matches that default.
|
||||
const DONE_RATIO = Number(window.DONE_RATIO ?? 0.95);
|
||||
let hls = null, detail = null, lang = "jpn", seasonId = null;
|
||||
|
||||
async function api(path) {
|
||||
@@ -190,7 +193,7 @@ const homeCard = x => {
|
||||
c.append(poster(x.poster, x.title));
|
||||
let meta = `E${x.ep} \u00b7 ${x.lang === "eng" ? "dub" : "sub"}`;
|
||||
if (done) meta += " \u00b7 \u2713";
|
||||
else if (x.dur > 0 && x.pos < x.dur * 0.95) meta += ` \u00b7 ${fmtMin((x.dur - x.pos) / 60)} left`;
|
||||
else if (x.dur > 0 && x.pos < x.dur * DONE_RATIO) meta += ` \u00b7 ${fmtMin((x.dur - x.pos) / 60)} left`;
|
||||
else if (hold) meta += ` \u00b7 ${Math.round(Date.now() / 1000 / 86400 - x.t / 86400)}d ago`;
|
||||
const info = el("div", "mini-info");
|
||||
info.append(el("div", "card-name", x.title), el("div", "mini-meta", meta));
|
||||
@@ -250,11 +253,11 @@ function showHome() {
|
||||
body.append(el("div", "hero-kicker", "continue watching"),
|
||||
el("h2", null, hero.title),
|
||||
el("div", "muted", `Ep ${hero.ep} · ${hero.lang === "eng" ? "dub" : "sub"} · ${fmtPos(hero.pos)} in` +
|
||||
(hero.dur > 0 && hero.pos < hero.dur * 0.95 ? ` · ${fmtMin((hero.dur - hero.pos) / 60)} left` : "") +
|
||||
(hero.dur > 0 && hero.pos < hero.dur * DONE_RATIO ? ` · ${fmtMin((hero.dur - hero.pos) / 60)} left` : "") +
|
||||
` · ${timeago(hero.t)}`));
|
||||
const p = bar(hero);
|
||||
if (p) body.append(p);
|
||||
const heroDone = hero.dur > 0 && hero.pos >= hero.dur * 0.95;
|
||||
const heroDone = hero.dur > 0 && hero.pos >= hero.dur * DONE_RATIO;
|
||||
const go = el("button", "btn resume", heroDone ? "\u25b6 Next ep" : "\u25b6 Resume");
|
||||
go.onclick = () => location.href = histHref(hero);
|
||||
right.append(body, go);
|
||||
@@ -503,7 +506,7 @@ async function showAnime(slug_id, opts = {}) {
|
||||
for (const x of await api("/api/history?all=1")) {
|
||||
if (x.slug_id !== slug_id || x.season_id !== seasonId) continue;
|
||||
started = true;
|
||||
if (x.dur > 0 && x.pos >= x.dur * 0.95) watchDone.add(String(x.ep_id));
|
||||
if (x.dur > 0 && x.pos >= x.dur * DONE_RATIO) watchDone.add(String(x.ep_id));
|
||||
else if (x.dur > 0) epProg.set(String(x.ep_id), Math.min(100, Math.round(100 * x.pos / x.dur)));
|
||||
}
|
||||
} catch {}
|
||||
@@ -529,7 +532,7 @@ async function showAnime(slug_id, opts = {}) {
|
||||
function langLabel() { return lang === "eng" ? "▶ dub" : "▶ sub"; }
|
||||
|
||||
// ---------- history page (full list + delete + client-side filter) ----------
|
||||
const histClass = x => x.dur > 0 && x.pos >= x.dur * 0.95 ? "done"
|
||||
const histClass = x => x.dur > 0 && x.pos >= x.dur * DONE_RATIO ? "done"
|
||||
: (x.t && Date.now() / 1000 - x.t > 7 * 86400 ? "hold" : "watching");
|
||||
function remapBoard() {
|
||||
// home: one stale card per stale anime (latest row), above the hero, so a
|
||||
@@ -1215,7 +1218,7 @@ async function play(ep_id, ep_no) {
|
||||
}
|
||||
if (saved?.pos > 10) {
|
||||
v.addEventListener("loadedmetadata", () => {
|
||||
if (saved.pos < v.duration * 0.95) v.currentTime = saved.pos;
|
||||
if (saved.pos < v.duration * DONE_RATIO) v.currentTime = saved.pos;
|
||||
}, {once: true});
|
||||
}
|
||||
v.onerror = () => playerFail("media error");
|
||||
|
||||
Reference in new issue
Block a user