diff --git a/src/app/components/message/content/PollContent.tsx b/src/app/components/message/content/PollContent.tsx index a06264e47..87a194970 100644 --- a/src/app/components/message/content/PollContent.tsx +++ b/src/app/components/message/content/PollContent.tsx @@ -261,52 +261,69 @@ export function PollContent({ handleVote(answers[idx].id); }; - const headerLabel = isEnded - ? 'Poll closed · Final results' - : `Poll · ${isMultiple ? 'Multiple choice' : 'Single choice'}`; + // [Gitea #246] Type line under the "Poll" label. + const typeLabel = (() => { + if (isEnded) return 'Final results'; + if (isUndisclosed) return 'Results hidden until the end'; + return isMultiple ? `Pick up to ${maxSelections}` : 'Single choice'; + })(); + // Multiple choice counts people, not answers ("1 voter" who picked two). + const unit = isMultiple ? 'voter' : 'vote'; const footerNote = (() => { + const totalPart = total > 0 ? `${total} ${unit}${total === 1 ? '' : 's'}` : `No ${unit}s yet`; if (isUndisclosed && !isEnded) { return canVote - ? 'Voting open · Results hidden until the poll ends' - : 'Results hidden until the poll ends'; + ? `${myVotes.size > 0 ? 'You voted' : 'Voting open'} · results shown when the poll ends` + : 'Results shown when the poll ends'; } - const votesPart = total > 0 ? `${total} vote${total === 1 ? '' : 's'}` : 'No votes yet'; - if (isEnded) return `${votesPart} · Poll closed`; - if (!canVote) return votesPart; - if (isMultiple) return `${votesPart} · Select up to ${maxSelections}`; - return `${votesPart} · ${myVotes.size > 0 ? 'Click to change' : 'Click to vote'}`; + if (isEnded) return `${totalPart} · Poll closed`; + if (!canVote) return totalPart; + return `${totalPart} · ${myVotes.size > 0 ? 'Select another answer to change your vote' : 'Select an answer to vote'}`; })(); + // Neutral tones derived from the theme's text colour, so they have contrast + // in every theme (the Container/ContainerLine tokens were near-invisible). + const muted = (pct: number) => + `color-mix(in srgb, ${color.SurfaceVariant.OnContainer} ${pct}%, transparent)`; + return ( - - ◉ - {headerLabel} - - - {question} - + + + + + Poll + + + · + + + {typeLabel} + + + + {question} + + 0 ? Math.round((voteCount / total) * 100) : 0; + const showBar = showResults && total > 0; + const pct = showBar ? Math.round((voteCount / total) * 100) : 0; const isWinner = winners.has(id); + const resultText = `${voteCount} ${voteCount === 1 ? 'vote' : 'votes'} · ${pct}%`; // Roving tabindex for the single-choice radiogroup; checkboxes stay tabbable. const tabIndex = isMultiple ? 0 : selected || (myVotes.size === 0 && i === 0) ? 0 : -1; + let barColor = muted(40); + if (isWinner) barColor = color.Success.Main; + else if (selected) barColor = color.Primary.Main; + let rowBorder = muted(22); + if (isWinner) rowBorder = color.Success.Main; + else if (selected) rowBorder = color.Primary.Main; + const labelParts = [text]; + if (showBar) labelParts.push(resultText); + if (isWinner) labelParts.push('winning answer'); return ( {showVoters && canShowVoters && (voters.get(id)?.length ?? 0) > 0 && ( {`Voted by ${(voters.get(id) ?? []).map((s) => getMemberName(room, s)).join(', ')}`} @@ -436,48 +484,56 @@ export function PollContent({ ); })} - {canShowVoters && ( - - setShowVoters((v) => !v)} - before={} - > - {showVoters ? 'Hide voters' : 'Show who voted'} - - - )} - - - {footerNote} + + + {footerNote} - {canEnd && - (confirmEnd ? ( - - - {ending ? 'Ending…' : 'End poll'} - - setConfirmEnd(false)}> - Cancel - - - ) : ( + + {canShowVoters && ( setConfirmEnd(true)} - before={} + aria-pressed={showVoters} + onClick={() => setShowVoters((v) => !v)} + before={} > - End poll + + {showVoters ? 'Hide voters' : 'Who voted'} + - ))} + )} + {canEnd && + (confirmEnd ? ( + <> + + + {ending ? 'Ending…' : 'End poll'} + + + setConfirmEnd(false)}> + + Cancel + + + + ) : ( + setConfirmEnd(true)} + before={} + > + + End poll + + + ))} + ); diff --git a/src/lotus-terminal.css.ts b/src/lotus-terminal.css.ts index d2e87eb1f..41cad0a14 100644 --- a/src/lotus-terminal.css.ts +++ b/src/lotus-terminal.css.ts @@ -898,6 +898,14 @@ globalStyle( boxShadow: '0 0 10px rgba(255,107,0,0.10)', }, ); +// [Gitea #246] The poll's winning answer (after it ends). +globalStyle( + `body.${lotusTerminalBodyClass} [data-poll-content] [data-poll-answer][data-winner="true"]`, + { + border: '1px solid rgba(0,255,136,0.55) !important', + boxShadow: '0 0 10px rgba(0,255,136,0.10)', + }, +); globalStyle(`body.${lotusTerminalBodyClass} [data-poll-content] [data-poll-content-label]`, { color: 'rgba(0,212,255,0.60) !important', opacity: '1 !important',