mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-10 19:37:03 +01:00
fix: the tagger ends on a screen, not on a button that stops working
Clicking "dalej" on the last photo did nothing, because move() clamped at the end. Everything had in fact been saved -- each toggle writes tags.json on the spot -- but the only way to find that out was to stop the tagger and read its summary, so the last photo answered "did that work?" with silence. The end of the album is now a screen: it says Gotowe, prints how many photos each command has, and offers a way back into the photos. The counts are distinct files rather than a sum per reading. A photo showing two of the three people an "either of them" entry covers is one photo that command can return, and summing claimed it twice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017w1HZ3cZ7neL3rFdQ6VMBA
This commit is contained in:
parent
86ea1b3220
commit
7f66116cd5
@ -57,6 +57,13 @@ ktokolwiek = ala | marek <span class="dim">← losowo jedno z nich</span></pre
|
||||
<p id="error" class="err"></p>
|
||||
</div>
|
||||
|
||||
<div id="done" hidden>
|
||||
<h1>Gotowe.</h1>
|
||||
<p class="hint">Wszystko zapisane. Komendy i ile mają zdjęć:</p>
|
||||
<pre class="hint sample" id="counts"></pre>
|
||||
<p><button id="again">← wróć do zdjęć</button></p>
|
||||
</div>
|
||||
|
||||
<div id="tagger" hidden>
|
||||
<div class="bar">
|
||||
<h1 id="progress"></h1>
|
||||
@ -168,11 +175,23 @@ async function toggle(k) {
|
||||
setTimeout(() => { document.getElementById("saved").textContent = ""; }, 800);
|
||||
}
|
||||
|
||||
function move(step) {
|
||||
async function move(step) {
|
||||
if (step > 0 && at === state.files.length - 1) {
|
||||
// The end of the album is a screen, not a button that stops working.
|
||||
await finish();
|
||||
return;
|
||||
}
|
||||
at = Math.min(state.files.length - 1, Math.max(0, at + step));
|
||||
draw();
|
||||
}
|
||||
|
||||
async function finish() {
|
||||
const {lines} = await api("/api/summary");
|
||||
document.getElementById("counts").textContent = lines.join("\n");
|
||||
document.getElementById("tagger").hidden = true;
|
||||
document.getElementById("done").hidden = false;
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (document.getElementById("tagger").hidden) { return; }
|
||||
if (event.key === "ArrowRight" || event.key === "Enter") { move(1); }
|
||||
@ -210,6 +229,11 @@ async function start() {
|
||||
|
||||
document.getElementById("prev").onclick = () => move(-1);
|
||||
document.getElementById("next").onclick = () => move(1);
|
||||
document.getElementById("again").onclick = () => {
|
||||
document.getElementById("done").hidden = true;
|
||||
document.getElementById("tagger").hidden = false;
|
||||
draw();
|
||||
};
|
||||
start();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@ -110,10 +110,12 @@ class Album:
|
||||
# exits, and a half-built pack is the normal state to stop in.
|
||||
return [*lines, f"!! the pack does not load yet: {error}"]
|
||||
for entry in pack.entries:
|
||||
counts = [len(pack.matching(option)) for option in entry.options]
|
||||
total = sum(counts)
|
||||
mark = " " if total else "!!"
|
||||
lines.append(f"{mark} {entry.triggers[0]}: {total} photo(s)")
|
||||
# Distinct files, not the sum per option: a photo showing two of
|
||||
# the three people an "either of them" entry covers is one photo
|
||||
# the command can return, and summing would claim it twice.
|
||||
reachable = {name for option in entry.options for name in pack.matching(option)}
|
||||
mark = " " if reachable else "!!"
|
||||
lines.append(f"{mark} {entry.triggers[0]}: {len(reachable)} photo(s)")
|
||||
return lines
|
||||
|
||||
|
||||
@ -166,6 +168,13 @@ def build_app(album: Album) -> FastAPI:
|
||||
album.tag(str(payload["file"]), [str(key) for key in payload.get("keys", [])])
|
||||
return {"status": "ok"}
|
||||
|
||||
@app.get("/api/summary")
|
||||
async def summary() -> dict[str, list[str]]:
|
||||
# The same lines the tagger prints when it stops. Shown in the page
|
||||
# too, because "I tagged everything, did it save?" is a question the
|
||||
# last photo used to answer by doing nothing at all.
|
||||
return {"lines": album.summary()}
|
||||
|
||||
@app.get("/media/{index}")
|
||||
async def media(index: int) -> FileResponse:
|
||||
# By index, never by a name the page sends back: a filename from a
|
||||
|
||||
Loading…
Reference in New Issue
Block a user