// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo, useState } from 'react';
import { Checkbox } from 'radix-ui';
import { tw } from '../../../axo/tw.js';
import { AxoButton } from '../../../axo/AxoButton.js';
import { AxoSymbol } from '../../../axo/AxoSymbol.js';
import type { DirectionType } from '../Message.js';
import type { PollWithResolvedVotersType } from '../../../state/selectors/message.js';
import type { LocalizerType } from '../../../types/Util.js';
import { PollVotesModal } from './PollVotesModal.js';
function VotedCheckmark({
isIncoming,
i18n,
}: {
isIncoming: boolean;
i18n: LocalizerType;
}): JSX.Element {
return (
);
}
type PollCheckboxProps = {
checked: boolean;
onCheckedChange: (nextChecked: boolean) => void;
isIncoming: boolean;
};
const PollCheckbox = memo((props: PollCheckboxProps) => {
const { isIncoming } = props;
return (
);
});
PollCheckbox.displayName = 'PollCheckbox';
export type PollMessageContentsProps = {
poll: PollWithResolvedVotersType;
direction: DirectionType;
i18n: LocalizerType;
};
export function PollMessageContents({
poll,
direction,
i18n,
}: PollMessageContentsProps): JSX.Element {
const [showVotesModal, setShowVotesModal] = useState(false);
const isIncoming = direction === 'incoming';
const totalVotes = poll.totalNumVotes;
let pollStatusText: string;
if (poll.terminatedAt) {
pollStatusText = i18n('icu:PollMessage--FinalResults');
} else if (poll.allowMultiple) {
pollStatusText = i18n('icu:PollMessage--SelectMultiple');
} else {
pollStatusText = i18n('icu:PollMessage--SelectOne');
}
return (
{poll.question}
{pollStatusText}
{/* Poll Options */}
{poll.options.map((option, index) => {
const pollVoteEntries = poll.votesByOption.get(index);
const optionVotes = pollVoteEntries?.length ?? 0;
const percentage =
totalVotes > 0 ? (optionVotes / totalVotes) * 100 : 0;
const weVotedForThis = (pollVoteEntries ?? []).some(
vote => vote.isMe && vote.optionIndexes.includes(index)
);
return (
// eslint-disable-next-line react/no-array-index-key
{poll.terminatedAt == null && (
// 3px offset: type-body-large has 14px font-size and 20px line-height,
// creating 3px space above text. This aligns checkbox with text baseline.
{}}
isIncoming={isIncoming}
/>
)}
{option}
{totalVotes > 0 && (
{poll.terminatedAt != null && weVotedForThis && (
)}
{optionVotes}
)}
);
})}
{totalVotes > 0 ? (
setShowVotesModal(true)}
>
{i18n('icu:PollMessage__ViewVotesButton')}
) : (
{i18n('icu:PollVotesModal__noVotes')}
)}
{showVotesModal && (
setShowVotesModal(false)}
/>
)}
);
}