ip specific votes + ui fixes
This commit is contained in:
@@ -193,6 +193,7 @@ body {
|
|||||||
/* ── Contestant ───────────────────────────────────────────────── */
|
/* ── Contestant ───────────────────────────────────────────────── */
|
||||||
|
|
||||||
.contestant {
|
.contestant {
|
||||||
|
position: relative;
|
||||||
border-left: 3px solid var(--accent);
|
border-left: 3px solid var(--accent);
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -343,14 +344,18 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.my-vote-tag {
|
.my-vote-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
font-family: var(--mono);
|
font-family: var(--mono);
|
||||||
font-size: 10px;
|
font-size: 9px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
padding: 3px 8px;
|
padding: 2px 6px;
|
||||||
border: 1px solid var(--text-muted);
|
border: 1px solid var(--text-muted);
|
||||||
color: var(--text-dim);
|
color: var(--text-dim);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Viewer Votes ────────────────────────────────────────────── */
|
/* ── Viewer Votes ────────────────────────────────────────────── */
|
||||||
|
|||||||
@@ -195,9 +195,9 @@ function ContestantCard({
|
|||||||
>
|
>
|
||||||
<div className="contestant__head">
|
<div className="contestant__head">
|
||||||
<ModelTag model={task.model} />
|
<ModelTag model={task.model} />
|
||||||
{isMyVote && <span className="my-vote-tag">YOUR PICK</span>}
|
|
||||||
{isWinner && <span className="win-tag">WIN</span>}
|
{isWinner && <span className="win-tag">WIN</span>}
|
||||||
</div>
|
</div>
|
||||||
|
{isMyVote && <span className="my-vote-tag">YOUR PICK</span>}
|
||||||
|
|
||||||
<div className="contestant__body">
|
<div className="contestant__body">
|
||||||
{!task.finishedAt ? (
|
{!task.finishedAt ? (
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ function setHistoryCache(key: string, body: string, expiresAt: number) {
|
|||||||
// ── WebSocket clients ───────────────────────────────────────────────────────
|
// ── WebSocket clients ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
const clients = new Set<ServerWebSocket<WsData>>();
|
const clients = new Set<ServerWebSocket<WsData>>();
|
||||||
const viewerVoters = new Map<ServerWebSocket<WsData>, "A" | "B">();
|
const viewerVoters = new Map<string, "A" | "B">();
|
||||||
let viewerVoteBroadcastTimer: ReturnType<typeof setTimeout> | null = null;
|
let viewerVoteBroadcastTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
function scheduleViewerVoteBroadcast() {
|
function scheduleViewerVoteBroadcast() {
|
||||||
@@ -624,14 +624,15 @@ const server = Bun.serve<WsData>({
|
|||||||
if (!round.viewerVotingEndsAt || Date.now() > round.viewerVotingEndsAt) return;
|
if (!round.viewerVotingEndsAt || Date.now() > round.viewerVotingEndsAt) return;
|
||||||
if (msg.votedFor !== "A" && msg.votedFor !== "B") return;
|
if (msg.votedFor !== "A" && msg.votedFor !== "B") return;
|
||||||
|
|
||||||
const previousVote = viewerVoters.get(ws);
|
const ip = ws.data.ip;
|
||||||
|
const previousVote = viewerVoters.get(ip);
|
||||||
if (previousVote === msg.votedFor) return; // same vote, ignore
|
if (previousVote === msg.votedFor) return; // same vote, ignore
|
||||||
|
|
||||||
// Undo previous vote if changing
|
// Undo previous vote if changing
|
||||||
if (previousVote === "A") round.viewerVotesA = Math.max(0, (round.viewerVotesA ?? 0) - 1);
|
if (previousVote === "A") round.viewerVotesA = Math.max(0, (round.viewerVotesA ?? 0) - 1);
|
||||||
else if (previousVote === "B") round.viewerVotesB = Math.max(0, (round.viewerVotesB ?? 0) - 1);
|
else if (previousVote === "B") round.viewerVotesB = Math.max(0, (round.viewerVotesB ?? 0) - 1);
|
||||||
|
|
||||||
viewerVoters.set(ws, msg.votedFor);
|
viewerVoters.set(ip, msg.votedFor);
|
||||||
if (msg.votedFor === "A") round.viewerVotesA = (round.viewerVotesA ?? 0) + 1;
|
if (msg.votedFor === "A") round.viewerVotesA = (round.viewerVotesA ?? 0) + 1;
|
||||||
else round.viewerVotesB = (round.viewerVotesB ?? 0) + 1;
|
else round.viewerVotesB = (round.viewerVotesB ?? 0) + 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user