A report may carry a screenshot
The 🐞 form takes a picture beside its words — PNG, JPEG, or WebP, under 2.5 MB, previewed before sending. The socket's message cap is far too small for one, so the picture goes through a plain HTTP door after the report is filed, addressed to the report's id, one per report within the hour, checked by its own first bytes, and kept in feedback-images/ beside the reports with a line on the report saying so. The desk's skill knows where to look. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
d76a18d5e6
commit
48350a3686
@@ -4,6 +4,10 @@ import type { Command, GameEvent, GameView, Side } from "@wizwar/engine";
|
||||
import { cardDef } from "@wizwar/engine";
|
||||
import { receiptFor } from "./receipt";
|
||||
|
||||
/** The same server over plain HTTP, for the one door a socket cannot carry: a picture. */
|
||||
const API_URL =
|
||||
import.meta.env.VITE_WIZWAR_SERVER ? String(import.meta.env.VITE_WIZWAR_SERVER).replace(/^ws/, "http")
|
||||
: location.port === "5173" ? `http://${location.hostname}:8787` : "";
|
||||
const SERVER_URL =
|
||||
import.meta.env.VITE_WIZWAR_SERVER ??
|
||||
(location.port === "5173" // the vite dev server; anything else serves its own socket
|
||||
@@ -659,9 +663,17 @@ class Net {
|
||||
case "feedbackList":
|
||||
this.feedbackReports = msg.reports ?? [];
|
||||
break;
|
||||
case "feedbackReceived":
|
||||
case "feedbackReceived": {
|
||||
const image = this.pendingImage;
|
||||
this.pendingImage = null;
|
||||
if (image && typeof msg.id === "string") {
|
||||
fetch(`${API_URL}/api/feedback-image/${msg.id}`, { method: "POST", headers: { "content-type": image.type }, body: image })
|
||||
.then((r) => { if (!r.ok) this.flash("The words went through; the picture did not — a PNG or JPEG under 2.5 MB, please"); })
|
||||
.catch(() => this.flash("The words went through; the picture did not"));
|
||||
}
|
||||
this.refreshFeedback();
|
||||
break;
|
||||
}
|
||||
case "games": {
|
||||
this.games = msg.games;
|
||||
for (const g of msg.games as GameSummary[]) {
|
||||
@@ -773,7 +785,10 @@ class Net {
|
||||
}
|
||||
|
||||
/** A surprise report: the server pins it to the room and move number. */
|
||||
sendFeedback(happened: string, expected: string): void {
|
||||
/** A screenshot waiting for its report's id, then posted beside it. */
|
||||
private pendingImage: File | null = null;
|
||||
sendFeedback(happened: string, expected: string, image: File | null = null): void {
|
||||
this.pendingImage = image;
|
||||
this.send({ type: "feedback", happened, expected });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user