Limit player name lengths and fix vote UI defaults
This commit is contained in:
@@ -195,7 +195,8 @@ function renderVotes() {
|
||||
const votesMap = Object.fromEntries(state.myVotes.map((v) => [v.suggestionId, v.score]));
|
||||
state.allSuggestions.forEach((s) => {
|
||||
const li = buildCard(s, { showAuthor: true, allowEdit: !!state.me?.isAdmin });
|
||||
const current = votesMap[s.id] ?? 0;
|
||||
const hasVote = Object.prototype.hasOwnProperty.call(votesMap, s.id);
|
||||
const current = hasVote ? votesMap[s.id] : 5; // start neutral when no prior vote
|
||||
const footer = document.createElement("div");
|
||||
footer.className = "vote-controls";
|
||||
footer.innerHTML = `
|
||||
@@ -339,6 +340,7 @@ function setupHandlers() {
|
||||
e.preventDefault();
|
||||
const username = $("login-username").value.trim();
|
||||
const password = $("login-password").value;
|
||||
if (username.length > 24) return toast("Username must be 24 characters or fewer.", true);
|
||||
if (!username || !password) return toast(t("auth.needCredentials"), true);
|
||||
try {
|
||||
await api.login({ username, password });
|
||||
@@ -362,6 +364,9 @@ function setupHandlers() {
|
||||
const password = $("register-password").value;
|
||||
const displayName = $("register-displayName").value.trim();
|
||||
const adminKey = $("register-adminkey").value.trim();
|
||||
if (!displayName) return toast(t("toast.displayNameRequired") || "Display name is required.", true);
|
||||
if (username.length > 24) return toast("Username must be 24 characters or fewer.", true);
|
||||
if (displayName.length > 16) return toast("Display name must be 16 characters or fewer.", true);
|
||||
if (!username || !password) return toast(t("auth.needCredentials"), true);
|
||||
try {
|
||||
await api.register({ username, password, displayName, adminKey });
|
||||
@@ -496,7 +501,7 @@ function buildCard(s, { showAuthor = false, allowDelete = false, allowEdit = fal
|
||||
${visual}
|
||||
<div class="card-body">
|
||||
<div class="card-title-row">
|
||||
<h3>${s.name}</h3>
|
||||
<h3 class="card-title" title="${s.name}">${s.name}</h3>
|
||||
<div class="title-meta">
|
||||
${showAuthor && s.author ? `<span class="chip">${s.author}</span>` : ""}
|
||||
${allowEdit ? `<button class="chip" data-edit="${s.id}" type="button">${t("card.edit")}</button>` : ""}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<form id="login-form" class="stack auth-form" data-mode="login">
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.username">Username</span>
|
||||
<input id="login-username" name="username" maxlength="64" autocomplete="username" required />
|
||||
<input id="login-username" name="username" maxlength="24" autocomplete="username" required />
|
||||
</label>
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.password">Password</span>
|
||||
@@ -42,7 +42,7 @@
|
||||
<form id="register-form" class="stack auth-form hidden" data-mode="register">
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.username">Username</span>
|
||||
<input id="register-username" name="username" maxlength="64" autocomplete="username" required />
|
||||
<input id="register-username" name="username" maxlength="24" autocomplete="username" required />
|
||||
</label>
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.password">Password</span>
|
||||
@@ -50,7 +50,7 @@
|
||||
</label>
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.displayName">Display name (shows to group)</span>
|
||||
<input id="register-displayName" name="displayName" maxlength="64" required />
|
||||
<input id="register-displayName" name="displayName" maxlength="16" required />
|
||||
</label>
|
||||
<label class="stack">
|
||||
<span class="label" data-i18n="auth.adminKey">Admin key (optional)</span>
|
||||
|
||||
@@ -93,6 +93,7 @@ const translations = {
|
||||
"toast.suggestionDeleted": "Suggestion deleted",
|
||||
"toast.savedChanges": "Saved changes",
|
||||
"toast.nameRequired": "Name required",
|
||||
"toast.displayNameRequired": "Display name is required",
|
||||
"toast.invalidImageUrl": "Screenshot URL must be http(s) and end with an image file.",
|
||||
|
||||
"modal.editTitle": "Edit game",
|
||||
@@ -196,6 +197,7 @@ const translations = {
|
||||
"toast.suggestionDeleted": "Vorschlag gelöscht",
|
||||
"toast.savedChanges": "Änderungen gespeichert",
|
||||
"toast.nameRequired": "Name erforderlich",
|
||||
"toast.displayNameRequired": "Anzeigename ist erforderlich",
|
||||
"toast.invalidImageUrl": "Screenshot-URL muss mit http(s) beginnen und auf eine Bilddatei enden.",
|
||||
|
||||
"modal.editTitle": "Spiel bearbeiten",
|
||||
|
||||
@@ -163,7 +163,8 @@ button.ghost { background: transparent; border-color: #d5c7b5; color: #2c1c0d; }
|
||||
|
||||
h3 { margin: 0; font-size: 18px; }
|
||||
|
||||
.card-title-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
|
||||
.card-title-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-width: 0; }
|
||||
.card-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.title-meta { display: flex; align-items: center; gap: 8px; }
|
||||
p { margin: 0; }
|
||||
.muted { color: #7a6a53; margin: 0; }
|
||||
|
||||
Reference in New Issue
Block a user