Bestenliste, Devlog-Filter, Galerie und leere Bereiche
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:
@@ -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 = ?'
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user