Skip to content

Commit

Permalink
Add a chunk-based progress tracking
Browse files Browse the repository at this point in the history
There will be no progress bar if there is only a single chunk to be uploaded.
  • Loading branch information
dtdesign committed Jun 21, 2024
1 parent c0933d4 commit 4ad932a
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
37 changes: 37 additions & 0 deletions ts/WoltLabSuite/Core/Component/Attachment/Entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,38 @@ function markElementAsErroneous(element: HTMLElement, errorMessage: string): voi
element.append(errorElement);
}

function trackUploadProgress(element: HTMLElement, file: WoltlabCoreFileElement): void {
const progress = document.createElement("progress");
progress.classList.add("attachment__item__progress__bar");
progress.max = 100;
const readout = document.createElement("span");
readout.classList.add("attachment__item__progress__readout");

file.addEventListener("uploadProgress", (event: CustomEvent<number>) => {
progress.value = event.detail;
readout.textContent = `${event.detail}%`;

if (progress.parentNode === null) {
element.classList.add("attachment__item--uploading");

const wrapper = document.createElement("div");
wrapper.classList.add("attachment__item__progress");
wrapper.append(progress, readout);

element.append(wrapper);
}
});
}

function removeUploadProgress(element: HTMLElement): void {
if (!element.classList.contains("attachment__item--uploading")) {
return;
}

element.classList.remove("attachment__item--uploading");
element.querySelector(".attachment__item__progress")?.remove();
}

export function createAttachmentFromFile(file: WoltlabCoreFileElement, editor: HTMLElement) {
const element = document.createElement("li");
element.classList.add("attachment__item");
Expand All @@ -212,7 +244,12 @@ export function createAttachmentFromFile(file: WoltlabCoreFileElement, editor: H
})
.catch((reason) => {
fileInitializationFailed(element, file, reason);
})
.finally(() => {
removeUploadProgress(element);
});

trackUploadProgress(element, file);

return element;
}
17 changes: 16 additions & 1 deletion ts/WoltLabSuite/Core/Component/File/Upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async function upload(element: WoltlabCoreFileUploadElement, file: File): Promis

const chunkSize = Math.ceil(file.size / numberOfChunks);

// TODO: Can we somehow report any meaningful upload progress?
notifyChunkProgress(fileElement, 0, numberOfChunks);

for (let i = 0; i < numberOfChunks; i++) {
const start = i * chunkSize;
Expand All @@ -81,6 +81,8 @@ async function upload(element: WoltlabCoreFileUploadElement, file: File): Promis
throw response.error;
}

notifyChunkProgress(fileElement, i + 1, numberOfChunks);

await chunkUploadCompleted(fileElement, response.value);

if (response.value.completed) {
Expand All @@ -89,6 +91,19 @@ async function upload(element: WoltlabCoreFileUploadElement, file: File): Promis
}
}

function notifyChunkProgress(element: WoltlabCoreFileElement, currentChunk: number, numberOfChunks: number): void {
// Suppress the progress bar for uploads that are processed in a single
// request, because we cannot track the upload progress within a chunk.
if (numberOfChunks === 1) {
return;
}

const event = new CustomEvent<number>("uploadProgress", {
detail: Math.floor((currentChunk / numberOfChunks) * 100),
});
element.dispatchEvent(event);
}

async function chunkUploadCompleted(fileElement: WoltlabCoreFileElement, result: UploadChunkResponse): Promise<void> {
if (!result.completed) {
return;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions wcfsetup/install/files/style/ui/attachment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,17 @@ html[data-color-scheme="dark"] {
justify-content: end;
}

.attachment__item__progress {
align-items: center;
column-gap: 10px;
display: flex;
grid-area: buttons;
}

.attachment__item__progress__readout {
@include wcfFontSmall;
}

.formAttachmentContent {
.formAttachmentList {
display: flex;
Expand Down

0 comments on commit 4ad932a

Please sign in to comment.