Config: Speichern-Leiste und durchsuchbare Kanal-Auswahl
Der Speichern-Knopf stand am Seitenende und war bei den zweispaltigen Bereichen oft gar nicht zu sehen. Vor allem gab es keinen Hinweis, dass etwas offen ist — wer einen Kanal umstellte und neu lud, verlor die Änderung kommentarlos. Jetzt erscheint unten eine Leiste, sobald sich etwas vom gespeicherten Stand unterscheidet: Anzahl der Änderungen, Verwerfen, Speichern. Beim Verlassen mit offenen Änderungen fragt der Browser nach. Der Vergleich zieht Bot-Name und -Beschreibung mit ein, die außerhalb des Formulars gepflegt werden. Die 27 Kanal- und Rollen-Auswahlen sind keine nativen Dropdowns mehr, sondern dieselbe durchsuchbare Liste wie bei den gamedig-IDs: tippen filtert, Enter nimmt den ersten Treffer. Bei zwölf Kanälen merkt man das schon, bei fünfzig ist es der Unterschied. Beim Testen zwei echte Fehler gefunden, beide älter als diese Änderung: Nicht gesetzte Kanäle kommen als null aus der API. String(null) ist "null" — also eine Kanal-ID, die es nie gibt. Auf einer frischen Installation scheiterte damit das Speichern *jeder* Einstellung, solange Devlog- oder Commit-Kanal leer waren. Sichtbar wurde das erst, weil die Leiste jetzt überall auftaucht statt nur auf vier Bereichen. Außerdem wurde jeder Kanal im Formular geprüft, auch die unveränderten. Ein inzwischen gelöschter Kanal hätte damit das Speichern aller anderen Einstellungen dauerhaft blockiert. Geprüft wird jetzt nur, was sich gegenüber dem ausgelieferten Stand wirklich ändert. Nachtrag zum Selbsttest: der erste Versuch, die Auswahlen per Regex zu ersetzen, lief mit DOTALL und griff dadurch über <select>-Grenzen hinweg — zwei fremde Dropdowns wurden zerlegt. Der Build hat es gemeldet, die Datei wurde zurückgesetzt und der Ersatz zeilenweise wiederholt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+20
-3
@@ -664,6 +664,11 @@ ${rssItems}
|
||||
if (requireScope(request, reply, 'settings')) return;
|
||||
|
||||
const body = request.body ?? {};
|
||||
// Stand vor der Änderung — und zwar genau so, wie ihn GET /api/settings
|
||||
// ausliefert (Einstellung ODER Env-Fallback). Nur daran lässt sich
|
||||
// ablesen, was das Formular wirklich geändert hat.
|
||||
const before = currentSettings();
|
||||
const unchanged = (key, value) => value === String(before[key] ?? '');
|
||||
|
||||
// Sensible Felder sind Owner-only — für Team-Mitglieder still ignorieren
|
||||
if (!isAdmin(getSessionUser(request))) {
|
||||
@@ -683,10 +688,21 @@ ${rssItems}
|
||||
'events_announce_channel_id', 'social_announce_channel_id', 'server_alert_channel_id',
|
||||
'birthday_channel_id',
|
||||
];
|
||||
// Auch Devlog- und Commit-Kanal dürfen leer sein: leer heißt „noch nicht
|
||||
// eingerichtet", und der Bot kommt damit klar. Vorher scheiterte das
|
||||
// Speichern JEDER Einstellung, solange einer der beiden nicht gesetzt war
|
||||
// — auf einer frischen Installation also immer.
|
||||
for (const key of ['commit_channel_id', 'devlog_channel_id', ...OPTIONAL_CHANNELS]) {
|
||||
if (body[key] === undefined) continue;
|
||||
const value = String(body[key]);
|
||||
if (value === '' && OPTIONAL_CHANNELS.includes(key)) {
|
||||
// `?? ''` ist wichtig: nicht gesetzte Kanäle kommen als null aus der
|
||||
// API zurück, und String(null) wäre "null" — also ein Kanal, den es
|
||||
// nie gibt.
|
||||
const value = String(body[key] ?? '');
|
||||
// Nur geprüft, was sich tatsächlich ändert. Sonst blockiert ein
|
||||
// inzwischen gelöschter Kanal das Speichern *aller* Einstellungen,
|
||||
// weil das Formular ihn unverändert mitschickt.
|
||||
if (unchanged(key, value)) continue;
|
||||
if (value === '') {
|
||||
setSetting(key, '');
|
||||
continue;
|
||||
}
|
||||
@@ -699,7 +715,8 @@ ${rssItems}
|
||||
// Rollen: müssen existieren ('' = Feature aus)
|
||||
for (const key of ['devlog_ping_role_id', 'playtester_role_id', 'autorole_id', 'birthday_role_id']) {
|
||||
if (body[key] === undefined) continue;
|
||||
const value = String(body[key]);
|
||||
const value = String(body[key] ?? ''); // null = keine Rolle, siehe oben
|
||||
if (unchanged(key, value)) continue; // unverändert → nicht prüfen
|
||||
if (value !== '') {
|
||||
const exists = [...client.guilds.cache.values()].some((g) =>
|
||||
g.roles?.cache?.has?.(value)
|
||||
|
||||
Reference in New Issue
Block a user