Bestenliste, Devlog-Filter, Galerie und leere Bereiche
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

Vier Stellen, die beim Durchsehen der Seiten aufgefallen sind.

Die Bestenliste zeigte nur Namen — und für Platz 1 bis 3 denselben Pokal
ohne Nummer, wodurch die Reihenfolge nur an der Position erkennbar war.
Jetzt: Rangnummer, Avatar und die ersten drei Plätze farblich abgesetzt.
Die Avatare kommen aus dem Member-Cache, der durch den GuildMembers-Intent
ohnehin gefüllt ist — das kostet keinen einzigen Discord-Aufruf. Wer nicht
im Cache liegt, bekommt seinen Anfangsbuchstaben statt eines leeren Kreises.

Die Projekt-Chips im Devlog-Archiv waren bloß Beschriftung. Jetzt filtern
Chips mit Anzahl nach Projekt (ECOGAME / D4RKBOT) — man will meist nur
eins von beiden lesen. Serverseitig über LIKE auf die erste Zeile, wo das
Projekt ohnehin steht; das spart eine Spalte und eine Migration. Eine
aktive Suche schlägt den Filter, sonst müsste die Volltextsuche beides
verbinden, ohne dass jemand danach fragt.

Galerie: Vorschaubilder von 240 auf 340 Pixel, und Name plus Datum stehen
dauerhaft am Bild statt nur beim Überfahren — am Handy gab es kein Hover
und damit nie eine Zuordnung.

Events, Changelog, Galerie und Level endeten bei wenig Inhalt mit einem
einzelnen Satz in einer sonst leeren Seite; das sah nach Fehler aus statt
nach „noch nichts da". Jetzt steht dort ein Block mit Symbol, Erklärung
was hier erscheinen wird, und Verweisen auf belebte Bereiche.

Dazu ein Sprung-nach-oben-Knopf im Devlog-Archiv und im Changelog, die
beide sehr lang werden.

Beim Testen gefunden: ESCAPE '\' in einem JS-String kommt als leeres
Zeichen in SQLite an ("ESCAPE expression must be a single character") —
der Backslash müsste doppelt entwertet werden. Jetzt ist das Escape-Zeichen
ein Ausrufezeichen, das die Falle gar nicht erst aufmacht.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 17:44:57 +02:00
co-authored by Claude Fable 5
parent c6977f9c4a
commit 2e58268f8d
11 changed files with 314 additions and 32 deletions
+28
View File
@@ -997,6 +997,34 @@ export function listDevlogs(limit, offset) {
return { items: selectDevlogs.all(limit, offset), total: countDevlogsStmt.get().n };
}
// Nach Projekt filtern. Das Projekt steht in der ersten Zeile („Devlog — X"),
// es gibt dafür keine eigene Spalte — LIKE auf den Anfang reicht und kommt
// ohne Migration aus.
const selectDevlogsByProject = db.prepare(`
SELECT message_id, content, author_name, posted_at, images
FROM devlogs WHERE content LIKE ? ESCAPE '!' ORDER BY posted_at DESC LIMIT ? OFFSET ?
`);
const countDevlogsByProject = db.prepare(
"SELECT COUNT(*) AS n FROM devlogs WHERE content LIKE ? ESCAPE '!'"
);
export function listDevlogsByProject(project, limit, offset) {
// Escape-Zeichen ist `!` und nicht der übliche Backslash: der müsste hier
// zweimal entwertet werden (einmal für JavaScript, einmal für SQL) und
// landet dadurch leicht als leere Zeichenkette in der Abfrage.
const escaped = String(project).replace(/[!%_]/g, (c) => `!${c}`);
const pattern = `Devlog — ${escaped}%`;
return {
items: selectDevlogsByProject.all(pattern, limit, offset),
total: countDevlogsByProject.get(pattern).n,
};
}
/** Erste Zeile aller Devlogs — daraus leitet die API die Projektliste ab */
const selectDevlogHeadsStmt = db.prepare('SELECT content FROM devlogs');
export const devlogHeads = () =>
selectDevlogHeadsStmt.all().map((r) => String(r.content).split('\n', 1)[0]);
const getDevlogStmt = db.prepare(
'SELECT message_id, content, author_name, posted_at, images FROM devlogs WHERE message_id = ?'
);