WELCOME TO KIYOSHI'S HOME – TAKE A LOOK!
🎭 11/17 wait 🩻
🎭 Message me on insta to earn something interesting... but you gotta figure out the secret word to get said item you only have one try every 2 years 🩻
import React, { useRef, useState } from "react"; // Image & Video Uploader (auto-playing video preview) // Supports only images and videos, manual upload with progress display export default function ImageVideoUploader() { const [uploads, setUploads] = useState([]); // { id, file, previewUrl, type, progress, status } const inputRef = useRef(null); const acceptTypes = [ "image/png", "image/jpeg", "image/jpg", "image/webp", "image/gif", "video/mp4", "video/webm", "video/ogg" ]; const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB function handleFiles(selectedFiles) { const validFiles = []; for (const file of Array.from(selectedFiles)) { if (!acceptTypes.includes(file.type) || file.size > MAX_FILE_SIZE) continue; const id = Math.random().toString(36).slice(2, 9); const previewUrl = URL.createObjectURL(file); const type = file.type.startsWith("video") ? "video" : "image"; validFiles.push({ id, file, previewUrl, type, progress: 0, status: "pending" }); } if (validFiles.length) setUploads(prev => [...prev, ...validFiles]); } async function uploadFile(upload) { const form = new FormData(); form.append("file", upload.file); try { const xhr = new XMLHttpRequest(); xhr.open("POST", "/api/upload"); // change this endpoint as needed xhr.upload.onprogress = e => { if (e.lengthComputable) { const percent = Math.round((e.loaded / e.total) * 100); setUploads(prev => prev.map(u => (u.id === upload.id ? { ...u, progress: percent } : u))); } }; xhr.onload = () => { if (xhr.status === 200) { setUploads(prev => prev.map(u => (u.id === upload.id ? { ...u, status: "done", progress: 100 } : u))); } else { setUploads(prev => prev.map(u => (u.id === upload.id ? { ...u, status: "error" } : u))); } }; xhr.onerror = () => { setUploads(prev => prev.map(u => (u.id === upload.id ? { ...u, status: "error" } : u))); }; xhr.send(form); } catch (err) { console.error("Upload failed", err); } } function uploadAll() { uploads.forEach(u => { if (u.status === "pending" || u.status === "error") { setUploads(prev => prev.map(f => (f.id === u.id ? { ...f, status: "uploading" } : f))); uploadFile(u); } }); } function onInputChange(e) { handleFiles(e.target.files); e.target.value = null; } function onDrop(e) { e.preventDefault(); handleFiles(e.dataTransfer.files); } function onDragOver(e) { e.preventDefault(); } function removeFile(id) { setUploads(prev => { const target = prev.find(f => f.id === id); if (target) URL.revokeObjectURL(target.previewUrl); return prev.filter(f => f.id !== id); }); } return (

Image & Video Uploader

inputRef.current?.click()} role="button" tabIndex={0} >

Drag & drop or click to add images/videos

Only images & videos up to 50MB

{uploads.length > 0 && ( <>
{uploads.map(u => (
{u.type === "image" ? ( preview ) : ( )}
{u.file.name}
{u.status}
))}
)}
); }