mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-15 02:43:17 +02:00
1 parent
db81507b7c
commit
843ad1986e
9 files changed
+259
-78
No files matched your search
+36
-16
@@ -171,18 +171,41 @@ export function GetDownloadUrl(RootName, RelativePath) {
|
||||
return `${ApiBase}/download?${Params}`;
|
||||
}
|
||||
|
||||
export async function UploadFiles(RootName, RelativePath, Files) {
|
||||
// Uploads go through XMLHttpRequest: unlike fetch, it reports how much has
|
||||
// been sent. OnProgress(BytesSent) is optional.
|
||||
function PostFormWithProgress(Url, Form, OnProgress) {
|
||||
return new Promise((Resolve, Reject) => {
|
||||
const Request = new XMLHttpRequest();
|
||||
Request.open("POST", Url);
|
||||
Request.withCredentials = true;
|
||||
if (OnProgress) {
|
||||
Request.upload.onprogress = (Event) => OnProgress(Event.loaded);
|
||||
}
|
||||
Request.onload = () => {
|
||||
let Body = null;
|
||||
try {
|
||||
Body = JSON.parse(Request.responseText);
|
||||
} catch {
|
||||
Body = null;
|
||||
}
|
||||
if (Request.status >= 200 && Request.status < 300) {
|
||||
Resolve(Body);
|
||||
} else {
|
||||
Reject(new Error(Body && Body.detail ? Body.detail : Request.statusText || `Upload failed (${Request.status})`));
|
||||
}
|
||||
};
|
||||
Request.onerror = () => Reject(new Error("Upload failed: couldn't reach the server."));
|
||||
Request.send(Form);
|
||||
});
|
||||
}
|
||||
|
||||
export function UploadFiles(RootName, RelativePath, Files, OnProgress) {
|
||||
const Form = new FormData();
|
||||
for (const File of Files) {
|
||||
Form.append("Files", File);
|
||||
}
|
||||
const Params = new URLSearchParams({ Root: RootName, Path: RelativePath });
|
||||
const Response = await fetch(`${ApiBase}/upload?${Params}`, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
body: Form,
|
||||
});
|
||||
return ParseJsonOrThrow(Response);
|
||||
return PostFormWithProgress(`${ApiBase}/upload?${Params}`, Form, OnProgress);
|
||||
}
|
||||
|
||||
const UploadChunkSizeBytes = 20 * 1024 * 1024;
|
||||
@@ -199,7 +222,7 @@ function GenerateUploadId() {
|
||||
return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
||||
}
|
||||
|
||||
async function UploadFileChunk(RootName, RelativePath, UploadId, ChunkIndex, TotalChunks, FileName, ChunkBlob) {
|
||||
function UploadFileChunk(RootName, RelativePath, UploadId, ChunkIndex, TotalChunks, FileName, ChunkBlob, OnProgress) {
|
||||
const Form = new FormData();
|
||||
Form.append("Chunk", ChunkBlob, "chunk");
|
||||
const Params = new URLSearchParams({
|
||||
@@ -210,12 +233,7 @@ async function UploadFileChunk(RootName, RelativePath, UploadId, ChunkIndex, Tot
|
||||
TotalChunks: String(TotalChunks),
|
||||
FileName,
|
||||
});
|
||||
const Response = await fetch(`${ApiBase}/upload/chunk?${Params}`, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
body: Form,
|
||||
});
|
||||
return ParseJsonOrThrow(Response);
|
||||
return PostFormWithProgress(`${ApiBase}/upload/chunk?${Params}`, Form, OnProgress);
|
||||
}
|
||||
|
||||
function CompleteChunkedUpload(RootName, RelativePath, UploadId, TotalChunks, FileName) {
|
||||
@@ -229,14 +247,16 @@ function CompleteChunkedUpload(RootName, RelativePath, UploadId, TotalChunks, Fi
|
||||
return FetchJson(`/upload/complete?${Params}`, { method: "POST" });
|
||||
}
|
||||
|
||||
export async function UploadFileChunked(RootName, RelativePath, File) {
|
||||
// OnProgress(BytesSent) counts across all the chunks.
|
||||
export async function UploadFileChunked(RootName, RelativePath, File, OnProgress) {
|
||||
const UploadId = GenerateUploadId();
|
||||
const TotalChunks = Math.max(1, Math.ceil(File.size / UploadChunkSizeBytes));
|
||||
|
||||
for (let ChunkIndex = 0; ChunkIndex < TotalChunks; ChunkIndex++) {
|
||||
const Start = ChunkIndex * UploadChunkSizeBytes;
|
||||
const ChunkBlob = File.slice(Start, Start + UploadChunkSizeBytes);
|
||||
await UploadFileChunk(RootName, RelativePath, UploadId, ChunkIndex, TotalChunks, File.name, ChunkBlob);
|
||||
await UploadFileChunk(RootName, RelativePath, UploadId, ChunkIndex, TotalChunks, File.name, ChunkBlob,
|
||||
OnProgress && ((Sent) => OnProgress(Start + Math.min(Sent, ChunkBlob.size))));
|
||||
}
|
||||
|
||||
return CompleteChunkedUpload(RootName, RelativePath, UploadId, TotalChunks, File.name);
|
||||
|
||||
Reference in new issue
Block a user