Handle new report submission process

This commit is contained in:
2023-10-19 16:50:11 -04:00
parent a132fd667f
commit a3a5308d81
2 changed files with 188 additions and 84 deletions

View File

@ -10,6 +10,7 @@ import {
Input,
Link,
Text,
Textarea,
useToast,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
@ -96,9 +97,8 @@ export default function () {
).value
.replaceAll(" ", "")
.split(",");
const file = (
document.getElementById("evidence") as HTMLInputElement
).files?.item(0);
const files = (document.getElementById("evidence") as HTMLInputElement)
.files;
if (!usernames.length)
return toast({
@ -108,9 +108,9 @@ export default function () {
title: "Error",
});
if (!file)
if (!files?.length)
return toast({
description: "Must attach a file",
description: "Must attach at least one file",
isClosable: true,
status: "error",
title: "Error",
@ -124,10 +124,29 @@ export default function () {
title: "Too Many Usernames",
});
if (!logged_in && !turnstileToken)
return toast({
description: "Please complete the captcha and try again",
isClosable: true,
status: "error",
title: "Captcha not completed",
});
const description = (
document.getElementById("description") as HTMLTextAreaElement
).value;
const filelist = [];
for (const file of files) {
filelist.push({ name: file.name, size: file.size });
}
const submitReq = await fetch("/api/reports/submit", {
body: JSON.stringify({
filename: file.name,
filesize: file.size,
description: description || undefined,
files: filelist,
turnstileResponse: logged_in ? undefined : turnstileToken,
usernames,
}),
headers: {
@ -152,42 +171,62 @@ export default function () {
});
}
const { id, upload_url }: { id: string; upload_url: string } =
const { id, upload_urls }: { id: string; upload_urls: string[] } =
await submitReq.json();
setUploading(true);
const reader = file.stream().getReader();
const totalSize = filelist.reduce((a, b) => a + b.size, 0);
let bytesRead = 0;
let shouldRecall = false;
const uploadReq = await fetch(upload_url, {
body: supportsRequestStreams
? new ReadableStream({
async pull(controller) {
const chunk = await reader.read();
setUploading(true);
if (chunk.done) {
controller.close();
setUploading(false);
return;
}
for (let i = 0; i < upload_urls.length; i++) {
const reader = files[i].stream().getReader();
controller.enqueue(chunk.value);
bytesRead += chunk.value.length;
setFileProgress(Math.floor((bytesRead / file.size) * 100));
},
})
: file,
// @ts-expect-error
duplex: supportsRequestStreams ? "half" : undefined,
headers: {
"content-type":
file.type ||
fileTypes[file.name.split(".")[file.name.split(".").length - 1]],
},
method: "PUT",
}).catch(console.error);
try {
const uploadReq = await fetch(upload_urls[i], {
body: supportsRequestStreams
? new ReadableStream({
async pull(controller) {
const chunk = await reader.read();
if (!uploadReq?.ok) {
if (chunk.done) {
controller.close();
if (i === upload_urls.length - 1) setUploading(false);
return;
}
controller.enqueue(chunk.value);
bytesRead += chunk.value.length;
setFileProgress(Math.floor((bytesRead / totalSize) * 100));
},
})
: files[i],
// @ts-expect-error
duplex: supportsRequestStreams ? "half" : undefined,
headers: {
"content-type":
files[i].type ||
fileTypes[files[i].name.split(".").at(-1) as string],
},
method: "PUT",
});
if (!uploadReq.ok) {
shouldRecall = true;
break;
}
} catch (e) {
console.error(e);
shouldRecall = true;
break;
}
}
if (shouldRecall) {
await fetch("/api/reports/recall", {
body: JSON.stringify({ id }),
headers: {
@ -245,7 +284,7 @@ export default function () {
</FormControl>
<br />
<FormControl isRequired>
<FormLabel>Your Evidence (Max Size: 512MB)</FormLabel>
<FormLabel>Your Evidence (Max size per file: 512MB)</FormLabel>
<Button
colorScheme="blue"
mr="8px"
@ -256,6 +295,11 @@ export default function () {
<input id="evidence" multiple type="file" />
</FormControl>
<br />
<FormControl>
<FormLabel>Optional description</FormLabel>
<Textarea id="description" maxLength={512} />
</FormControl>
<br />
<div
className="cf-turnstile"
data-callback="setToken"