feat(api): allow bulk uploading (#97)

This commit is contained in:
diced 2021-09-05 11:23:52 -07:00
parent 771cc380df
commit 5c980c21e5
No known key found for this signature in database
GPG key ID: 85AB64C74535D76E
3 changed files with 44 additions and 29 deletions

View file

@ -8,19 +8,21 @@ import Alert from 'components/Alert';
import { useStoreSelector } from 'lib/redux/store';
import CenteredBox from 'components/CenteredBox';
import copy from 'copy-to-clipboard';
import Link from 'components/Link';
export default function Upload({ route }) {
const user = useStoreSelector(state => state.user);
const [file, setFile] = useState(null);
const [files, setFiles] = useState([]);
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const [severity, setSeverity] = useState('success');
const [message, setMessage] = useState('Saved');
console.log(files);
const handleUpload = async () => {
const body = new FormData();
body.append('file', file);
for (let i = 0; i !== files.length; ++i) body.append('file', files[i]);
setLoading(true);
const res = await fetch('/api/upload', {
@ -34,8 +36,11 @@ export default function Upload({ route }) {
if (res.ok && json.error === undefined) {
setOpen(true);
setSeverity('success');
setMessage(`Copied to clipboard! ${json.url}`);
//@ts-ignore
setMessage(<>Copied first image to clipboard! <br/>{json.files.map(x => (<Link key={x} href={x}>{x}<br/></Link>))}</>);
copy(json.url);
setFiles([]);
} else {
setOpen(true);
setSeverity('error');
@ -50,7 +55,7 @@ export default function Upload({ route }) {
<Alert open={open} setOpen={setOpen} message={message} severity={severity} />
<Typography variant='h4' pb={2}>Upload file</Typography>
<Dropzone onDrop={acceptedFiles => setFile(acceptedFiles[0])}>
<Dropzone onDrop={acceptedFiles => setFiles([...files, ...acceptedFiles])}>
{({getRootProps, getInputProps}) => (
<CardActionArea>
<Paper
@ -67,7 +72,9 @@ export default function Upload({ route }) {
<input {...getInputProps()} />
<CenteredBox><UploadIcon sx={{ fontSize: 100 }} /></CenteredBox>
<CenteredBox><Typography variant='h5'>Drag an image or click to upload an image.</Typography></CenteredBox>
<CenteredBox><Typography variant='h6'>{file && file.name}</Typography></CenteredBox>
{files.map(file => (
<CenteredBox key={file.name}><Typography variant='h6'>{file.name}</Typography></CenteredBox>
))}
</Paper>
</CardActionArea>
)}

View file

@ -30,7 +30,7 @@ export type NextApiReq = NextApiRequest & {
} | null | void>;
getCookie: (name: string) => string | null;
cleanCookie: (name: string) => void;
file?: NextApiFile;
files?: NextApiFile[];
}
export type NextApiRes = NextApiResponse & {

View file

@ -20,11 +20,19 @@ async function handler(req: NextApiReq, res: NextApiRes) {
token: req.headers.authorization
}
});
if (!user) return res.forbid('authorization incorect');
if (!req.file) return res.error('no file');
if (req.file.size > zconfig.uploader[user.administrator ? 'admin_limit' : 'user_limit']) return res.error('file size too big');
const ext = req.file.originalname.split('.').pop();
if (!user) return res.forbid('authorization incorect');
if (!req.files) return res.error('no files');
if (req.files && req.files.length === 0) return res.error('no files');
const files = [];
for (let i = 0; i !== req.files.length; ++i) {
const file = req.files[i];
if (file.size > zconfig.uploader[user.administrator ? 'admin_limit' : 'user_limit']) return res.error('file size too big');
const ext = file.originalname.split('.').pop();
if (zconfig.uploader.disabled_extentions.includes(ext)) return res.error('disabled extension recieved: ' + ext);
const rand = randomChars(zconfig.uploader.length);
@ -32,7 +40,7 @@ async function handler(req: NextApiReq, res: NextApiRes) {
const image = await prisma.image.create({
data: {
file: `${rand}.${ext}`,
mimetype: req.file.mimetype,
mimetype: file.mimetype,
userId: user.id,
embed: !!req.headers.embed
}
@ -40,13 +48,13 @@ async function handler(req: NextApiReq, res: NextApiRes) {
if (req.headers.zws) invis = await createInvis(zconfig.uploader.length, image.id);
await writeFile(join(process.cwd(), zconfig.uploader.directory, image.file), req.file.buffer);
await writeFile(join(process.cwd(), zconfig.uploader.directory, image.file), file.buffer);
Logger.get('image').info(`User ${user.username} (${user.id}) uploaded an image ${image.file} (${image.id})`);
files.push(`${zconfig.core.secure ? 'https' : 'http'}://${req.headers.host}${zconfig.uploader.route}/${invis ? invis.invis : image.file}`);
}
return res.json({
url: `${zconfig.core.secure ? 'https' : 'http'}://${req.headers.host}${zconfig.uploader.route}/${invis ? invis.invis : image.file}`
});
// url will be deprecated soon
return res.json({ files, url: files[0] });
}
function run(middleware: any) {
@ -60,7 +68,7 @@ function run(middleware: any) {
}
export default async function handlers(req, res) {
await run(uploader.single('file'))(req, res);
await run(uploader.array('file'))(req, res);
return withZipline(handler)(req, res);
};