Die Dogen-Muenzen: drei Saetze zu je drei Stufen
Filipe, 28.09.2026: "ich werde die drei varianten schicken fuer niedrige spenden. mittlere und hohe spenden. alle drei varianten will ich drauf so dass ich sie aussuchen kann wie ich will. aber pass sie sofort diesen 3 kategorien an." DIE ZUORDNUNG IST GELESEN, NICHT GERATEN In allen drei Saetzen geht es nacktes Metall -> Steinkranz -> Vollbesatz; Filipes Dateinummern (01/02/03) und die Uhrzeiten seiner Entwuerfe laufen genau mit. Klassik: Palladium, Gold mit Saphir, Diamant. Amethyst: Stahl, Rosegold, Vollbesatz. Neon: Chrom auf Schwarz, Steinkranz, Vollbesatz. AUS 25 MB WURDEN 443 KB Je Bild 320 px WebP statt 1254 px PNG, Faktor 58. Die Zahl ist gemessen: Groesster Fall in der Seite 110 px (Karte, hoechste Stufe), auf der OBS-Tafel 189 px, bei doppelter Bildschirmdichte rund 220. Drei Megabyte fuer ein 24-Pixel-Zeichen waeren ein Ladebalken mitten in der Sendung -- wer auf dem Handy zusieht, bekaeme die Karte, wenn sie schon wieder weg ist. Die Originale liegen neben den Datenbanksicherungen, nicht im Repo: 26 MB, die bei jedem Klon mitkaemen und die niemand ausliefert. WELCHE MUENZE WANN -- ABGELEITET STATT GEPFLEGT "Niedrig, mittel, hoch" gibt es im Haus schon: die Stufenleiter. Zwei eigene Grenzen daneben waeren eine zweite Antwort auf dieselbe Frage, und spaetestens beim Verschieben einer Stufe zeigte die Muenze etwas anderes an als der Name auf der Karte. Die Leiter wird deshalb in DRITTEL geteilt -- bei den drei Werksstufen genau eine je Muenze, bei sechs zwei je Muenze, bei einer einzigen ueberall die mittlere. DIE MUENZE STEHT AUCH GROSS AUF DER KARTE Sonst haette Filipe neun Bilder fuer ein 24-Pixel-Zeichen gezeichnet. "dogen" ist dafuer eine neue Vorlage neben Herz, Welle und Krone -- und die drei Werksstufen bekommen sie EINMAL zugeteilt, nur wo noch die Werksvorlage steht und kein eigenes Bild hochgeladen ist. Wer danach ein Herz zurueckstellt, findet es morgen nicht wieder als Muenze vor: Eine Einstellung, die sich gegen den Benutzer durchsetzt, wird abgeschafft. Und steht sie gross da, nimmt das Stilblatt die kleine neben der Zahl weg -- dieselbe Muenze in zwei Groessen auf einer Karte sieht aus wie ein Versehen. AM BILDSCHIRMFOTO NACHGEBESSERT Bei 0,92em blieb an den Spendenknoepfen ein 13,5-Pixel-Fleck uebrig; bei einem flachen Symbol reicht das, bei einer Muenze mit Pfote, Schriftzug und Steinen nicht. Jetzt 1,05em ueberall und 1,6em auf den Knoepfen. In der Auswahl sahen "Amethyst" und "Neon" bei 40 px praktisch gleich aus -- und genau sie auseinanderzuhalten ist der Zweck dieser Liste. Jetzt 56/64/72 px. Und was gewaehlt ist, steht als WORT da: Neben neun glaenzenden Muenzen geht ein ruhiger Rahmen unter, und wer Farben schlecht unterscheidet, sieht ihn gar nicht. EIN SATZWECHSEL ERREICHT ALLE Die Karten trugen ihren Satz immer selbst mit und waren richtig. Die Muenzen an den Spendenknoepfen und beim eigenen Stand aber nicht -- die holt eine Seite nur bei einer Spende neu. Eine Einstellung, die nur dort ankommt, wo sie gemacht wurde, ist keine Einstellung des Hauses. ZWEI BEFUNDE GEGEN DIE PRUEFUNG SELBST 1. Sie verlangte "erste Grenze ECHT kleiner als zweite". Bei genau zwei Stufen fallen beide absichtlich zusammen -- sie meldete einen Fehler, wo das Verhalten richtig ist. 2. Sie prueft die Muenzverteilung jetzt auf einer FRISCHEN Datenbank. Vorher lief sie auf der, die ein frueherer Abschnitt umgebaut hatte: Eine Pruefung, die den eigenen Kollateralschaden misst, misst sich selbst. Dazu eine Gegenprobe, dass eine selbst gewaehlte Vorlage NICHT ueberschrieben wird. UND DREI AN DER MESSUNG Sie suchte noch die gezeichnete Muenze (svg), wo jetzt ein Bild liegt. Umgestellt nicht auf "ist ein img da", sondern auf `naturalWidth > 0` -- ob es etwas ZEIGT. Ein img, das 404 antwortet, steht genauso im Dokument wie eines, das laedt; auf dem Bildschirm ist an seiner Stelle nichts. Und beim Satzwechsel las sie die vorige Karte, die noch acht Sekunden stand: Die Karten laufen in einer Schlange, also wird auf das Merkmal gewartet, das nur die neue hat. pruef-spenden 167/0 (vorher 136) - pruef-reaktion 321/0 - pruef-css-klassen ok - pruef-tippziele 11/0 - mess-reaktion und mess-buehne ohne Beanstandung Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+143
-14
@@ -46,6 +46,7 @@ import {
|
||||
VORLAGEN, STUFEN_MAX, DAUER_MS_MIN, DAUER_MS_MAX,
|
||||
GROESSE_MIN, GROESSE_MAX, BILD_MAX_BYTES,
|
||||
centInMille, milleInCent, ZEICHEN_NAME,
|
||||
DOGEN_SAETZE, DOGEN_STUFEN, SATZ_NAME, muenzeAdresse,
|
||||
} from "./spenden-tabellen.js";
|
||||
|
||||
const BILDER = join(DATEN_ORDNER, "spendenbilder");
|
||||
@@ -284,7 +285,7 @@ function alsKarte(z) {
|
||||
die eine Karte zeigt, an zwei Dinge denken muss. Die Karte
|
||||
traegt alles, was sie braucht; genau das verspricht
|
||||
spendenkarte.js in ihrem Kopf. */
|
||||
zeichen: zeichenAdresse(),
|
||||
zeichen: zeichenSatz(),
|
||||
name: z.name,
|
||||
gruss: z.gruss,
|
||||
herkunft: z.herkunft,
|
||||
@@ -307,15 +308,98 @@ function bildAdresse(datei) {
|
||||
return datei ? `/workspace/api/buehne/spendenbild/${datei}` : "";
|
||||
}
|
||||
|
||||
/** Das Dogen-Zeichen, wenn eines hochgeladen wurde.
|
||||
/* ======================================================================
|
||||
WELCHE MUENZE ZU WELCHER SPENDE
|
||||
|
||||
Filipe: „ich werde die drei varianten schicken fuer niedrige
|
||||
spenden. mittlere und hohe spenden."
|
||||
|
||||
---------------------------------------------------------------------
|
||||
DIE GRENZEN WERDEN ABGELEITET UND NICHT GEPFLEGT
|
||||
|
||||
„Niedrig, mittel, hoch" gibt es im Haus schon -- das ist die
|
||||
Stufenleiter. Zwei eigene Grenzen daneben waeren eine zweite
|
||||
Antwort auf dieselbe Frage, und spaetestens wenn Filipe eine Stufe
|
||||
verschiebt, zeigte die Muenze etwas anderes an als der Name auf
|
||||
der Karte.
|
||||
|
||||
Die Leiter wird deshalb in DRITTEL geteilt. Bei den drei Stufen ab
|
||||
Werk ist das genau eine je Muenze. Bei sechs Stufen sind es zwei
|
||||
je Muenze -- und bei einer einzigen gibt es kein Oben und Unten,
|
||||
dann steht ueberall die mittlere.
|
||||
====================================================================== */
|
||||
function zeichenGrenzen() {
|
||||
try {
|
||||
const leiter = db().prepare("SELECT ab_cent FROM spenden_stufen ORDER BY ab_cent")
|
||||
.all().map((z) => centInMille(z.ab_cent));
|
||||
const n = leiter.length;
|
||||
/* Ohne Leiter und bei genau einer Stufe gibt es keine Rangfolge:
|
||||
alles bekommt die mittlere Muenze. Die Untergrenze 0 erreicht
|
||||
niemand (Betraege sind immer groesser), die Obergrenze ist
|
||||
unerreichbar gross -- also faellt alles dazwischen. */
|
||||
if (n < 2) return [0, Number.MAX_SAFE_INTEGER];
|
||||
if (n === 2) return [leiter[1], leiter[1]];
|
||||
return [leiter[Math.floor(n / 3)], leiter[Math.floor((2 * n) / 3)]];
|
||||
} catch { return [0, Number.MAX_SAFE_INTEGER]; }
|
||||
}
|
||||
|
||||
/** Der gewaehlte Satz -- mit allen drei Muenzen und den Grenzen.
|
||||
*
|
||||
* Filipe: „die symbole schick ich dir spaeter."
|
||||
* ==== EINE FORM UEBERALL
|
||||
*
|
||||
* Bis dahin ist die Antwort leer, und die Oberflaeche zeichnet
|
||||
* selbst eine Muenze. Ein Platzhalterbild, das wie eine kaputte
|
||||
* Datei aussieht, waere schlechter als eine saubere Zeichnung. */
|
||||
function zeichenAdresse() {
|
||||
return bildAdresse(einstellung(ZEICHEN_NAME, ""));
|
||||
* Die Karte, die Listen, die Knoepfe und der eigene Stand zeigen
|
||||
* alle dieselbe Muenze zur selben Zahl. Wuerde der Server fuer die
|
||||
* Karte EINE Adresse schicken und fuer den Rest die Auswahl, gaebe
|
||||
* es zwei Formen desselben Dinges -- und die Oberflaeche muesste an
|
||||
* jeder Stelle wissen, welche gerade kommt. Also immer die Auswahl;
|
||||
* wer sie benutzt, rechnet aus der Zahl.
|
||||
*
|
||||
* „eigen" ist der vierte Satz: ein hochgeladenes Bild, das fuer
|
||||
* alle drei Stufen gilt. Wer ein einzelnes Zeichen hochlaedt, meint
|
||||
* ein Zeichen und keine Rangfolge. */
|
||||
function zeichenSatz() {
|
||||
const eigen = einstellung(ZEICHEN_NAME, "");
|
||||
const gewuenscht = einstellung(SATZ_NAME, "") || DOGEN_SAETZE[0].schluessel;
|
||||
/* WAS NICHT GEHT, FAELLT AUF DEN ERSTEN SATZ ZURUECK -- etwa
|
||||
„eigen", nachdem das Bild geloescht wurde. Ein leeres Zeichen
|
||||
waere sonst ein kaputtes Bild neben jeder Zahl. */
|
||||
const satz = gewuenscht === "eigen" && eigen ? "eigen"
|
||||
: DOGEN_SAETZE.some((x) => x.schluessel === gewuenscht) ? gewuenscht
|
||||
: DOGEN_SAETZE[0].schluessel;
|
||||
|
||||
const bild = (stufe) => (satz === "eigen"
|
||||
? bildAdresse(eigen)
|
||||
: muenzeAdresse(satz, stufe));
|
||||
return {
|
||||
satz,
|
||||
eigen: eigen ? bildAdresse(eigen) : "",
|
||||
niedrig: bild("niedrig"),
|
||||
mittel: bild("mittel"),
|
||||
hoch: bild("hoch"),
|
||||
grenzen: zeichenGrenzen(),
|
||||
};
|
||||
}
|
||||
|
||||
/** Alle Saetze zum Aussuchen -- Filipe: „alle drei varianten will
|
||||
* ich drauf so dass ich sie aussuchen kann wie ich will." */
|
||||
function alleSaetze() {
|
||||
const eigen = einstellung(ZEICHEN_NAME, "");
|
||||
const liste = DOGEN_SAETZE.map((x) => ({
|
||||
...x,
|
||||
bilder: Object.fromEntries(DOGEN_STUFEN.map((st) => [st, muenzeAdresse(x.schluessel, st)])),
|
||||
}));
|
||||
/* Der eigene Satz steht nur da, wenn es ihn gibt. Ein leerer
|
||||
vierter Knopf waere eine Auswahl, die nichts auswaehlt. */
|
||||
if (eigen) {
|
||||
const a = bildAdresse(eigen);
|
||||
liste.push({
|
||||
schluessel: "eigen",
|
||||
name: "Eigenes Zeichen",
|
||||
wort: "Dein hochgeladenes Bild, fuer alle drei Stufen",
|
||||
bilder: Object.fromEntries(DOGEN_STUFEN.map((st) => [st, a])),
|
||||
});
|
||||
}
|
||||
return liste;
|
||||
}
|
||||
|
||||
/** Wen die Leitung einer Spende zuordnen kann.
|
||||
@@ -374,9 +458,12 @@ spendenRouter.get("/workspace/api/spenden", (req, res) => {
|
||||
umgestellt wurden, waere genau diese Kopie die stehen
|
||||
gebliebene gewesen. */
|
||||
stufen: stufenLesen(),
|
||||
/* Das Zeichen, das neben jeder Zahl steht. Leer, solange
|
||||
keines hochgeladen ist. */
|
||||
zeichen: zeichenAdresse(),
|
||||
/* Die Muenzen, die neben jeder Zahl stehen -- und die zwei
|
||||
Grenzen, an denen sich entscheidet, welche. */
|
||||
zeichen: zeichenSatz(),
|
||||
/* Zum Aussuchen: nur fuer die Leitung. Ein Zuschauer soll das
|
||||
Bild sehen, nicht die Auswahl daneben. */
|
||||
saetze: darf ? alleSaetze() : null,
|
||||
/* WAS SICH EINSTELLEN LAESST, KOMMT VOM SERVER. Stuenden die
|
||||
Vorlagennamen und die Grenzen auch in der Oberflaeche, waeren
|
||||
es zwei Listen -- und die eine liefe irgendwann von der
|
||||
@@ -843,6 +930,38 @@ spendenRouter.post("/workspace/api/spenden/stufe/:id(\\d+)/bild", nurGeld,
|
||||
ohne Schranke ausliefert. Ein Zeichen, das nur angemeldet
|
||||
sichtbar waere, fehlte ausgerechnet im Stream.
|
||||
====================================================================== */
|
||||
/** Einen Satz auswaehlen. */
|
||||
spendenRouter.put("/workspace/api/spenden/zeichen/satz", nurGeld,
|
||||
express.json({ limit: "2kb" }), (req, res) => {
|
||||
try {
|
||||
const satz = String(req.body?.satz ?? "");
|
||||
const geht = DOGEN_SAETZE.some((x) => x.schluessel === satz)
|
||||
|| (satz === "eigen" && einstellung(ZEICHEN_NAME, ""));
|
||||
/* EIN SATZ, DEN ES NICHT GIBT, WIRD ABGELEHNT -- und „eigen"
|
||||
ohne hochgeladenes Bild gibt es nicht. Sonst stuende neben
|
||||
jeder Zahl ein Bild, das 404 antwortet. */
|
||||
if (!geht) return res.status(400).json({ fehler: "satz_unbekannt" });
|
||||
einstellungSetzen(SATZ_NAME, satz, req.person);
|
||||
/* ==== UND ALLE ERFAHREN ES ================================
|
||||
Die KARTEN tragen ihren Satz selbst mit und waren immer
|
||||
richtig. Die Muenzen an den Spendenknoepfen und beim eigenen
|
||||
Stand aber nicht: Die holt sich eine Seite nur bei einer
|
||||
Spende neu, und bis dahin stuende beim Zuschauer noch der
|
||||
alte Satz -- und in einem zweiten Regiefenster auch.
|
||||
Eine Einstellung, die nur dort ankommt, wo sie gemacht
|
||||
wurde, ist keine Einstellung des Hauses. */
|
||||
stromAn(empfaenger(), "spende", { was: "zeichen" });
|
||||
buehneMelden("spende", { was: "zeichen" });
|
||||
protokolliere("dogen_satz", {
|
||||
personId: req.person.id, detail: satz, ip: echteIp(req),
|
||||
});
|
||||
res.json({ ok: true, zeichen: zeichenSatz(), saetze: alleSaetze() });
|
||||
} catch (fehler) {
|
||||
console.error("[spenden] Satz:", fehler?.message);
|
||||
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||
}
|
||||
});
|
||||
|
||||
spendenRouter.post("/workspace/api/spenden/zeichen", nurGeld,
|
||||
express.raw({ type: "*/*", limit: BILD_MAX_BYTES }), zuGross, (req, res) => {
|
||||
try {
|
||||
@@ -855,6 +974,11 @@ spendenRouter.post("/workspace/api/spenden/zeichen", nurGeld,
|
||||
|
||||
const alt = einstellung(ZEICHEN_NAME, "");
|
||||
einstellungSetzen(ZEICHEN_NAME, name, req.person);
|
||||
/* WER EIN ZEICHEN HOCHLAEDT, WILL ES AUCH SEHEN. Ohne diese
|
||||
Zeile laege es in den Einstellungen und neben den Zahlen
|
||||
stuende weiter die Muenze -- und Filipe suchte den Fehler
|
||||
beim Hochladen. */
|
||||
einstellungSetzen(SATZ_NAME, "eigen", req.person);
|
||||
/* Das alte wegraeumen -- sonst bleibt bei jedem Wechsel eine
|
||||
Datei liegen, die niemand mehr findet. */
|
||||
if (alt && alt !== name) {
|
||||
@@ -865,7 +989,7 @@ spendenRouter.post("/workspace/api/spenden/zeichen", nurGeld,
|
||||
detail: `${Math.round(req.body.length / 1024)} KB`,
|
||||
ip: echteIp(req),
|
||||
});
|
||||
res.json({ ok: true, zeichen: zeichenAdresse() });
|
||||
res.json({ ok: true, zeichen: zeichenSatz(), saetze: alleSaetze() });
|
||||
} catch (fehler) {
|
||||
console.error("[spenden] Zeichen:", fehler?.message);
|
||||
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||
@@ -876,8 +1000,13 @@ spendenRouter.delete("/workspace/api/spenden/zeichen", nurGeld, (req, res) => {
|
||||
try {
|
||||
const alt = einstellung(ZEICHEN_NAME, "");
|
||||
einstellungSetzen(ZEICHEN_NAME, "", req.person);
|
||||
/* UND ZURUECK AUF EINEN SATZ, DEN ES GIBT. Bliebe „eigen"
|
||||
stehen, zeigte jede Zahl ein Bild, das es nicht mehr gibt. */
|
||||
if (einstellung(SATZ_NAME, "") === "eigen") {
|
||||
einstellungSetzen(SATZ_NAME, DOGEN_SAETZE[0].schluessel, req.person);
|
||||
}
|
||||
if (alt) { try { unlinkSync(join(BILDER, alt)); } catch { /* war weg */ } }
|
||||
res.json({ ok: true, zeichen: "" });
|
||||
res.json({ ok: true, zeichen: zeichenSatz(), saetze: alleSaetze() });
|
||||
} catch (fehler) {
|
||||
console.error("[spenden] Zeichen loeschen:", fehler?.message);
|
||||
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||
@@ -923,7 +1052,7 @@ spendenRouter.post("/workspace/api/spenden/probe", nurGeld,
|
||||
const karte = {
|
||||
id: 0,
|
||||
dogen_mille: centInMille(cent),
|
||||
zeichen: zeichenAdresse(),
|
||||
zeichen: zeichenSatz(),
|
||||
/* KENNTLICH ALS PROBE. Stuende hier ein Name, waere auf dem
|
||||
Bildschirmfoto nicht mehr zu unterscheiden, ob jemand
|
||||
gespendet hat. */
|
||||
|
||||
Reference in New Issue
Block a user