91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
|
|
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>
|
||
|
|
);
|
||
|
|
}
|