Freie Links je Server statt fester Felder
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

connect_url und mods_url waren zwei Spalten fuer zwei Zwecke — und beim
naechsten Zweck waere eine dritte dazugekommen. Jetzt gibt es eine Liste:
Beschriftung plus Adresse, so viele wie noetig. Regeln, TeamSpeak, Shop,
Bewerbung.

Als JSON-Spalte, nicht als eigene Tabelle: es haengt an genau einem Server,
wird immer komplett gelesen und immer komplett geschrieben. Gelesen wird es als
Liste, geschrieben darf es als Liste hereinkommen — better-sqlite3 kann kein
Array binden und wuerde sonst werfen. Kaputtes JSON ergibt eine leere Liste
statt eines Absturzes im Monitor.

Discord nimmt fuenf Knoepfe je Reihe; ab jetzt werden sie umgebrochen, bei
zwei Reihen ist Schluss. Die Grenze steht im Code und nicht im Fehler beim
Senden, den niemand sieht. Zu lange Beschriftungen werden auf 80 Zeichen
gekuerzt, halbe Zeilen fliegen raus statt als leerer Knopf zu erscheinen. Was
nicht http(s) ist — ts3server://, steam:// —, wird wie bisher ein Codeblock im
Embed zum Kopieren.

Dabei umbenannt: das Embed-Feld fuer einen nicht klickbaren Connect-Link hiess
"Connect", der Knopf daneben "Verbinden". Jetzt heisst beides gleich.

Geprueft: Umbruch bei zwoelf Links, Reihenfolge mit Connect und Mods vorn,
halbe Zeilen, ueberlange Beschriftung, nicht klickbare Schemata, fehlendes und
unbrauchbares links-Feld, dazu Speichern, Aendern und kaputtes JSON in der
Datenbank. Panel und /server-Seite im laufenden Frontend angesehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-09 13:39:10 +02:00
co-authored by Claude Opus 5
parent 5de172f862
commit b69cb6c5e4
6 changed files with 136 additions and 22 deletions
+31 -12
View File
@@ -142,17 +142,36 @@ export function istWebLink(url) {
* eckigen Klammern wörtlich da. Ein Knopf lässt diese Frage gar nicht erst
* aufkommen und ist obendrein als Knopf erkennbar.
*/
// Discord: fünf Knöpfe je Reihe. Mehr als zwei Reihen erschlägt das Embed,
// also ist bei zehn Schluss — und zwar sichtbar hier, nicht als Fehler beim
// Senden, den niemand sieht.
const PRO_REIHE = 5;
const MAX_REIHEN = 2;
/** Alle Links eines Servers in einer Liste: die festen zuerst, dann die freien */
export function serverLinks(r) {
return [
{ label: '🎮 Verbinden', url: r.connect_url },
{ label: '📦 Mods laden', url: r.mods_url },
...(Array.isArray(r.links) ? r.links : []),
].filter((l) => l?.url && String(l.label ?? '').trim());
}
export function serverKnoepfe(r) {
const knoepfe = [
['🎮 Verbinden', r.connect_url],
['📦 Mods laden', r.mods_url],
]
.filter(([, url]) => istWebLink(url))
.map(([label, url]) => new ButtonBuilder()
const knoepfe = serverLinks(r)
.filter((l) => istWebLink(l.url))
.slice(0, PRO_REIHE * MAX_REIHEN)
.map((l) => new ButtonBuilder()
.setStyle(ButtonStyle.Link)
.setLabel(label)
.setURL(url.trim()));
return knoepfe.length > 0 ? [new ActionRowBuilder().addComponents(knoepfe)] : [];
// Discord nimmt höchstens 80 Zeichen und weist längere ab
.setLabel(String(l.label).trim().slice(0, 80))
.setURL(l.url.trim()));
const reihen = [];
for (let i = 0; i < knoepfe.length; i += PRO_REIHE) {
reihen.push(new ActionRowBuilder().addComponents(knoepfe.slice(i, i + PRO_REIHE)));
}
return reihen;
}
/** Embed + Knöpfe — das, was der Monitor in den Kanal schreibt */
@@ -191,9 +210,9 @@ export function buildServerEmbed(r) {
// Connect und Mods stehen als Knopf darunter, wenn es https ist. Alles
// andere (fivem://, steam://) macht Discord nicht klickbar — dann lieber
// als Codeblock zum Kopieren, statt einen toten Link vorzugaukeln.
for (const [titel, url] of [['Connect', r.connect_url], ['Mods', r.mods_url]]) {
if (url && !istWebLink(url)) {
embed.addFields({ name: titel, value: `\`\`\`\n${url}\n\`\`\`` });
for (const l of serverLinks(r)) {
if (!istWebLink(l.url)) {
embed.addFields({ name: String(l.label).trim().slice(0, 256), value: `\`\`\`\n${l.url}\n\`\`\`` });
}
}
if (r.address) embed.addFields({ name: 'Adresse', value: `\`\`\`\n${r.address}\n\`\`\`` });