import { Checkbox, Dropdown, Label, Spinner, TextInput, Textarea } from 'flowbite-react' import { ChangeEvent, useEffect, useRef, useState } from 'react' import { FormattedMessage, useIntl } from 'react-intl' import { FaEnvelope, FaGlobe, FaListCheck, FaLock, FaLockOpen, FaPaperPlane, FaPaperclip, FaXmark } from 'react-icons/fa6' import { Entity, MegalodonInterface } from 'megalodon' import { useToast } from '@/utils/toast' type Props = { client: MegalodonInterface } export default function Compose(props: Props) { const [body, setBody] = useState('') const [visibility, setVisibility] = useState<'public' | 'unlisted' | 'private' | 'direct'>('public') const [cw, setCW] = useState(false) const [spoiler, setSpoiler] = useState('') const [attachments, setAttachments] = useState>([]) const [loading, setLoading] = useState(false) const { formatMessage } = useIntl() const uploaderRef = useRef(null) const showToast = useToast() useEffect(() => { if (!cw) { setSpoiler('') } }, [cw]) const post = async () => { if (body.length === 0) return let options = { visibility: visibility } if (cw) { options = Object.assign({}, options, { spoiler_text: spoiler }) } if (attachments.length > 0) { options = Object.assign({}, options, { media_ids: attachments.map(m => m.id) }) } const sensitive = document.getElementById('sensitive') as HTMLInputElement if (sensitive && sensitive.checked) { options = Object.assign({}, options, { sensitive: sensitive.checked }) } setLoading(true) try { await props.client.postStatus(body, options) reset() } finally { setLoading(false) } } const reset = () => { setBody('') setSpoiler('') setCW(false) setAttachments([]) } const selectFile = () => { if (uploaderRef.current) { uploaderRef.current.click() } } const fileChanged = async (event: ChangeEvent) => { const file = event.target.files?.item(0) if (file === null || file === undefined) { return } if (!file.type.includes('image') && !file.type.includes('video')) { showToast({ text: formatMessage({ id: 'alert.validation.attachment_type' }), type: 'failure' }) return } setLoading(true) try { const res = await props.client.uploadMedia(file) setAttachments(current => [...current, res.data]) } catch { showToast({ text: formatMessage({ id: 'alert.upload_error' }), type: 'failure' }) } finally { setLoading(false) } } const removeFile = (index: number) => { setAttachments(current => current.filter((_, i) => i !== index)) } return (
{cw && ( setSpoiler(ev.target.value)} placeholder={formatMessage({ id: 'compose.spoiler.placeholder' })} /> )}