Files
cinny/src/app/components/message/content/PollContent.tsx
T

91 lines
2.4 KiB
TypeScript
Raw Normal View History

import React from 'react';
import { Box, Text } from 'folds';
type PollTextValue = Array<{ body: string }> | string;
function extractText(val: PollTextValue | undefined): string {
if (!val) return '';
if (typeof val === 'string') return val;
return val[0]?.body ?? '';
}
type PollAnswer = {
'm.id'?: string;
id?: string;
'm.text'?: PollTextValue;
'org.matrix.msc3381.poll.answer'?: { body: string };
};
type PollData = {
question?: { body?: string; 'm.text'?: PollTextValue };
answers?: PollAnswer[];
};
export function PollContent({ content }: { content: Record<string, unknown> }) {
const poll = (
content['m.poll'] ?? content['org.matrix.msc3381.poll.start']
) as PollData | undefined;
if (!poll) {
return (
<Text style={{ opacity: 0.6 }}>
<i>Poll (unreadable format)</i>
</Text>
);
}
const questionText =
extractText((poll.question as any)?.['m.text']) ||
(poll.question as any)?.body ||
'Untitled poll';
return (
<Box direction="Column" gap="200" style={{ maxWidth: '340px', paddingTop: '2px', paddingBottom: '4px' }}>
<Box
alignItems="Center"
gap="100"
style={{
fontSize: '0.68rem',
fontWeight: 700,
letterSpacing: '0.12em',
textTransform: 'uppercase',
opacity: 0.55,
marginBottom: '2px',
}}
>
Poll
</Box>
<Text size="T400" style={{ fontWeight: 600 }}>
{questionText}
</Text>
<Box direction="Column" gap="100" style={{ marginTop: '2px' }}>
{(poll.answers ?? []).map((answer, i) => {
const text =
extractText((answer as any)['m.text']) ||
(answer as any)['org.matrix.msc3381.poll.answer']?.body ||
`Option ${i + 1}`;
const id = answer['m.id'] ?? answer.id ?? String(i);
return (
<div
key={id}
style={{
padding: '7px 12px',
borderRadius: '8px',
background: 'var(--bg-surface-low)',
border: '1px solid var(--bg-surface-border)',
fontSize: '0.88rem',
lineHeight: 1.4,
}}
>
{text}
</div>
);
})}
</Box>
<Text size="T200" style={{ opacity: 0.4, marginTop: '2px' }}>
<i>Open in Element to vote</i>
</Text>
</Box>
);
}