refactor post attachment input

This commit is contained in:
john 2025-05-05 21:30:35 +02:00
parent d35619308d
commit db1c642072

View file

@ -5,62 +5,55 @@ interface NewPostWidgetProps {
isSubmitting?: boolean isSubmitting?: boolean
} }
interface Thumbnail { interface Attachment {
id: string id: string
file: File
objectUrl: string objectUrl: string
} }
export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPostWidgetProps) { export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPostWidgetProps) {
const [content, setContent] = useState('') const [content, setContent] = useState('')
const [files, setFiles] = useState<{ id: string; file: File }[]>([]) const [attachments, setAttachments] = useState<Attachment[]>([])
const [thumbnails, setThumbnails] = useState<Thumbnail[]>([])
const handleContentChange = (e: ChangeEvent<HTMLTextAreaElement>) => { const handleContentChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setContent(e.target.value) setContent(e.target.value)
} }
const handleMediaChange = (e: ChangeEvent<HTMLInputElement>) => { const handleMediaChange = (e: ChangeEvent<HTMLInputElement>) => {
if (!(e.target.files && e.target.files.length > 0)) { const inputEl = e.target as HTMLInputElement
if (inputEl.files == null || inputEl.files.length === 0) {
return return
} }
const newFiles = Array.from(e.target.files).map((file) => ({ const newFiles = Array.from(inputEl.files).map((file) => ({
id: crypto.randomUUID(), id: crypto.randomUUID(),
file, file,
objectUrl: URL.createObjectURL(file),
})) }))
setFiles([...files, ...newFiles]) setAttachments((attachments) => [...attachments, ...newFiles])
inputEl.value = ''
const newThumbnails = newFiles.map((file) => {
return {
id: file.id,
objectUrl: URL.createObjectURL(file.file),
}
})
setThumbnails([...thumbnails, ...newThumbnails])
;(e.target as HTMLInputElement).value = ''
} }
const handleSubmit = () => { const handleSubmit = () => {
if (!content.trim() && files.length === 0) { if (!content.trim() && attachments.length === 0) {
return return
} }
onSubmit( onSubmit(
content, content,
files.map((file) => file.file), attachments.map(({ file }) => file),
) )
attachments.forEach(({ objectUrl }) => URL.revokeObjectURL(objectUrl))
setContent('') setContent('')
setFiles([]) setAttachments([])
thumbnails.forEach(({ objectUrl }) => URL.revokeObjectURL(objectUrl))
setThumbnails([])
} }
const handleRemoveMedia = (id: string) => { const handleRemoveMedia = (id: string) => {
setFiles(files.filter((file) => file.id !== id)) const attachment = attachments.find((attachment) => attachment.id === id)!
const { objectUrl } = thumbnails.find((thumbnail) => thumbnail.id === id)! setAttachments(attachments.filter((attachment) => attachment.id !== id))
URL.revokeObjectURL(objectUrl) URL.revokeObjectURL(attachment.objectUrl)
setThumbnails(thumbnails.filter((thumbnail) => thumbnail.id !== id))
} }
return ( return (
@ -74,9 +67,9 @@ export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPos
disabled={isSubmitting} disabled={isSubmitting}
/> />
{thumbnails.length > 0 && ( {attachments.length > 0 && (
<div className="flex flex-row flex-wrap gap-2 mb-3"> <div className="flex flex-row flex-wrap gap-2 mb-3">
{thumbnails.map(({ objectUrl, id }) => ( {attachments.map(({ objectUrl, id }) => (
<button <button
key={id} key={id}
className="relative cursor-pointer" className="relative cursor-pointer"
@ -104,7 +97,7 @@ export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPos
<button <button
className="px-4 py-2 bg-gray-800 text-white rounded-md hover:bg-gray-700 disabled:opacity-50" className="px-4 py-2 bg-gray-800 text-white rounded-md hover:bg-gray-700 disabled:opacity-50"
onClick={handleSubmit} onClick={handleSubmit}
disabled={isSubmitting || (content.trim() === '' && files.length === 0)} disabled={isSubmitting || (content.trim() === '' && attachments.length === 0)}
> >
Post Post
</button> </button>