import { useState } from 'react' import FancyTextEditor, { TextInputKeyDownEvent } from './inputs/FancyTextEditor.tsx' import Button from './buttons/Button.tsx' import { openFileDialog } from '../utils/openFileDialog.ts' interface NewPostWidgetProps { onSubmit: ( content: string, media: { file: File; width: number; height: number }[], isPublic: boolean, ) => void isSubmitting?: boolean } interface Attachment { id: string file: File objectUrl: string width: number height: number } export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPostWidgetProps) { const [content, setContent] = useState('') const [attachments, setAttachments] = useState([]) const [isPublic, setIsPublic] = useState(false) const onContentInput = (value: string) => { setContent(value) } async function onAddMediaClicked() { const files = await openFileDialog('image/*', true) if (files == null || files.length === 0) { return } const newAttachments = await Promise.all(Array.from(files).map(createAttachment)) setAttachments((attachments) => [...attachments, ...newAttachments]) } const handleSubmit = () => { if (!content.trim() && attachments.length === 0) { return } onSubmit(content, attachments, isPublic) attachments.forEach(({ objectUrl }) => URL.revokeObjectURL(objectUrl)) setContent('') setAttachments([]) } const handleRemoveMedia = (id: string) => { const attachment = attachments.find((attachment) => attachment.id === id)! setAttachments(attachments.filter((attachment) => attachment.id !== id)) URL.revokeObjectURL(attachment.objectUrl) } const onInputKeyDown = (e: TextInputKeyDownEvent) => { if (e.key === 'Enter' && e.ctrlKey) { e.preventDefault() handleSubmit() } } return (
{attachments.length > 0 && (
{attachments.map(({ objectUrl, id }) => ( ))}
)}
) } async function createAttachment(file: File): Promise { if (!file.type.startsWith('image/')) { throw new Error('not an image') } const objectUrl = URL.createObjectURL(file) const { width, height } = await getImageFileDimensions(objectUrl) return { id: crypto.randomUUID(), file, objectUrl, width, height, } } function getImageFileDimensions(objectURL: string): Promise<{ width: number; height: number }> { return new Promise((resolve) => { const img = document.createElement('img') img.addEventListener('load', () => { resolve({ width: img.width, height: img.height }) }) img.src = objectURL }) }