voting why not lol
This commit is contained in:
60
broadcast.ts
60
broadcast.ts
@@ -24,6 +24,9 @@ type RoundState = {
|
||||
votes: VoteInfo[];
|
||||
scoreA?: number;
|
||||
scoreB?: number;
|
||||
viewerVotesA?: number;
|
||||
viewerVotesB?: number;
|
||||
viewerVotingEndsAt?: number;
|
||||
};
|
||||
type GameState = {
|
||||
lastCompleted: RoundState | null;
|
||||
@@ -341,7 +344,7 @@ function drawScoreboard(scores: Record<string, number>) {
|
||||
function drawRound(round: RoundState) {
|
||||
const mainW = WIDTH - 380;
|
||||
|
||||
const phaseLabel =
|
||||
let phaseLabel =
|
||||
(round.phase === "prompting"
|
||||
? "Writing prompt"
|
||||
: round.phase === "answering"
|
||||
@@ -351,6 +354,12 @@ function drawRound(round: RoundState) {
|
||||
: "Complete"
|
||||
).toUpperCase();
|
||||
|
||||
// Append countdown during voting phase
|
||||
let countdownSeconds = 0;
|
||||
if (round.phase === "voting" && round.viewerVotingEndsAt) {
|
||||
countdownSeconds = Math.max(0, Math.ceil((round.viewerVotingEndsAt - Date.now()) / 1000));
|
||||
}
|
||||
|
||||
ctx.font = '700 22px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = "#ededed";
|
||||
const totalText = totalRounds !== null ? `/${totalRounds}` : "";
|
||||
@@ -360,6 +369,13 @@ function drawRound(round: RoundState) {
|
||||
const labelWidth = ctx.measureText(phaseLabel).width;
|
||||
ctx.fillText(phaseLabel, mainW - 64 - labelWidth, 150);
|
||||
|
||||
if (countdownSeconds > 0) {
|
||||
const countdownText = `${countdownSeconds}S`;
|
||||
ctx.fillStyle = "#ededed";
|
||||
const cdWidth = ctx.measureText(countdownText).width;
|
||||
ctx.fillText(countdownText, mainW - 64 - labelWidth - cdWidth - 12, 150);
|
||||
}
|
||||
|
||||
ctx.font = '600 18px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = "#888";
|
||||
const promptedText = "PROMPTED BY ";
|
||||
@@ -483,30 +499,38 @@ function drawContestantCard(
|
||||
const totalVotes = votesA + votesB;
|
||||
const pct = totalVotes > 0 ? Math.round((voteCount / totalVotes) * 100) : 0;
|
||||
|
||||
roundRect(x + 24, y + h - 60, w - 48, 4, 2, "#1c1c1c");
|
||||
const viewerVoteCount = isFirst ? (round.viewerVotesA ?? 0) : (round.viewerVotesB ?? 0);
|
||||
const totalViewerVotes = (round.viewerVotesA ?? 0) + (round.viewerVotesB ?? 0);
|
||||
const hasViewerVotes = totalViewerVotes > 0;
|
||||
|
||||
// Shift model votes up when viewer votes are present
|
||||
const modelVoteBarY = hasViewerVotes ? y + h - 110 : y + h - 60;
|
||||
const modelVoteTextY = hasViewerVotes ? y + h - 74 : y + h - 24;
|
||||
|
||||
roundRect(x + 24, modelVoteBarY, w - 48, 4, 2, "#1c1c1c");
|
||||
if (pct > 0) {
|
||||
roundRect(x + 24, y + h - 60, Math.max(8, ((w - 48) * pct) / 100), 4, 2, color);
|
||||
roundRect(x + 24, modelVoteBarY, Math.max(8, ((w - 48) * pct) / 100), 4, 2, color);
|
||||
}
|
||||
|
||||
ctx.font = '700 28px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillText(String(voteCount), x + 24, y + h - 24);
|
||||
ctx.fillText(String(voteCount), x + 24, modelVoteTextY);
|
||||
|
||||
ctx.font = '600 20px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = "#444";
|
||||
const vTxt = `vote${voteCount === 1 ? "" : "s"}`;
|
||||
const vCountW = ctx.measureText(String(voteCount)).width;
|
||||
const vTxtW = ctx.measureText(vTxt).width;
|
||||
ctx.fillText(vTxt, x + 24 + vCountW + 8, y + h - 25);
|
||||
ctx.fillText(vTxt, x + 24 + vCountW + 8, modelVoteTextY - 1);
|
||||
|
||||
let avatarX = x + 24 + vCountW + 8 + vTxtW + 16;
|
||||
const avatarY = y + h - 48;
|
||||
const avatarY = modelVoteBarY + 12;
|
||||
const avatarSize = 28;
|
||||
|
||||
for (const v of taskVoters) {
|
||||
const vColor = getColor(v.voter.name);
|
||||
const drewLogo = drawModelLogo(v.voter.name, avatarX, avatarY, avatarSize);
|
||||
|
||||
|
||||
if (!drewLogo) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, Math.PI * 2);
|
||||
@@ -518,9 +542,29 @@ function drawContestantCard(
|
||||
const tw = ctx.measureText(initial).width;
|
||||
ctx.fillText(initial, avatarX + avatarSize / 2 - tw / 2, avatarY + avatarSize / 2 + 4);
|
||||
}
|
||||
|
||||
|
||||
avatarX += avatarSize + 8;
|
||||
}
|
||||
|
||||
// Viewer votes
|
||||
if (hasViewerVotes) {
|
||||
const viewerPct = Math.round((viewerVoteCount / totalViewerVotes) * 100);
|
||||
|
||||
roundRect(x + 24, y + h - 56, w - 48, 4, 2, "#1c1c1c");
|
||||
if (viewerPct > 0) {
|
||||
roundRect(x + 24, y + h - 56, Math.max(8, ((w - 48) * viewerPct) / 100), 4, 2, "#666");
|
||||
}
|
||||
|
||||
ctx.font = '700 22px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = "#999";
|
||||
ctx.fillText(String(viewerVoteCount), x + 24, y + h - 22);
|
||||
|
||||
const vvCountW = ctx.measureText(String(viewerVoteCount)).width;
|
||||
ctx.font = '600 16px "JetBrains Mono", monospace';
|
||||
ctx.fillStyle = "#444";
|
||||
const vvTxt = `viewer vote${viewerVoteCount === 1 ? "" : "s"}`;
|
||||
ctx.fillText(vvTxt, x + 24 + vvCountW + 8, y + h - 23);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user