Handle new report submission process
This commit is contained in:
@ -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"
|
||||
|
Reference in New Issue
Block a user