Add voter tooltips across results emojis and average

This commit is contained in:
2026-02-17 19:06:05 +01:00
parent 4d62d0bf50
commit 26379eef1a
10 changed files with 107 additions and 11 deletions

View File

@@ -63,6 +63,12 @@ export function renderResults() {
const safeShot = safeUrl(r.screenshotUrl);
const safeGameUrl = safeUrl(r.gameUrl);
const safeYoutubeUrl = safeUrl(r.youtubeUrl);
const votersTooltip = buildVotersTooltip(r);
const safeVotersTooltip = escapeHtml(votersTooltip);
const averageScore =
r.average?.toFixed && typeof r.average === "number"
? r.average.toFixed(1)
: r.average;
row.innerHTML = `
<td class="rank-cell"><span class="medal">${medal}</span></td>
<td class="game-cell">
@@ -76,9 +82,9 @@ export function renderResults() {
</div>
</td>
<td class="author-cell">${safeAuthor || "—"}</td>
<td>${r.average?.toFixed ? r.average.toFixed(1) : r.average}</td>
<td>${formatVotes(r.votes)}</td>
<td>${formatMyVote(r.myVote)}</td>
<td><span title="${safeVotersTooltip}">${averageScore}</span></td>
<td>${formatVotes(r.votes, votersTooltip)}</td>
<td>${formatMyVote(r.myVote, votersTooltip)}</td>
<td>
${safeGameUrl ? `<a class="link compact" href="${safeGameUrl}" target="_blank" rel="noopener">${t("results.link.site")}</a><br>` : ""}
${safeYoutubeUrl ? `<a class="link compact" href="${safeYoutubeUrl}" target="_blank" rel="noopener">${t("results.link.youtube")}</a>` : ""}
@@ -110,13 +116,36 @@ function buildResultMeta(r) {
return `<div class="muted small">${bits.join(" • ")}</div>`;
}
function formatVotes(votes) {
if (!Array.isArray(votes) || votes.length === 0) return "⚠️";
function formatVotes(votes, tooltip) {
const safeTooltip = escapeHtml(tooltip);
if (!Array.isArray(votes) || votes.length === 0) {
return `<span class="score-emoji" title="${safeTooltip}">⚠️</span>`;
}
const sorted = [...votes].sort((a, b) => a - b);
return sorted.map((v) => scoreToEmoji(v)).join("");
return sorted
.map(
(v) =>
`<span class="score-emoji" title="${safeTooltip}">${scoreToEmoji(v)}</span>`,
)
.join("");
}
function formatMyVote(score) {
function formatMyVote(score, tooltip) {
if (score == null || Number.isNaN(score)) return "—";
return `${score} ${scoreToEmoji(score)}`;
const safeTooltip = escapeHtml(tooltip);
return `${score} <span class="score-emoji" title="${safeTooltip}">${scoreToEmoji(score)}</span>`;
}
function buildVotersTooltip(result) {
const voterNames = Array.isArray(result?.voterNames)
? result.voterNames
.filter(
(name) => typeof name === "string" && name.trim().length > 0,
)
.sort((a, b) =>
a.localeCompare(b, undefined, { sensitivity: "base" }),
)
: [];
if (voterNames.length === 0) return t("results.votersTooltipEmpty");
return t("results.votersTooltip", { users: voterNames.join(", ") });
}