From 598c956e4e516441a31dc848c850ff256ef4bb23 Mon Sep 17 00:00:00 2001
From: Matthew Penner <me@matthewp.io>
Date: Sun, 4 Dec 2022 16:36:53 -0700
Subject: [PATCH] ui(server): fix file uploads being canceled instead of
 completed

---
 .../server/files/FileManagerStatus.tsx        |  4 +--
 .../components/server/files/UploadButton.tsx  | 30 ++++++++++---------
 resources/scripts/state/server/files.ts       |  7 +++++
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/resources/scripts/components/server/files/FileManagerStatus.tsx b/resources/scripts/components/server/files/FileManagerStatus.tsx
index 620e067c..3e1c2df2 100644
--- a/resources/scripts/components/server/files/FileManagerStatus.tsx
+++ b/resources/scripts/components/server/files/FileManagerStatus.tsx
@@ -32,7 +32,7 @@ const Spinner = ({ progress, className }: { progress: number; className?: string
 
 const FileUploadList = () => {
     const { close } = useContext(DialogWrapperContext);
-    const removeFileUpload = ServerContext.useStoreActions((actions) => actions.files.removeFileUpload);
+    const cancelFileUpload = ServerContext.useStoreActions((actions) => actions.files.cancelFileUpload);
     const clearFileUploads = ServerContext.useStoreActions((actions) => actions.files.clearFileUploads);
     const uploads = ServerContext.useStoreState((state) =>
         Object.entries(state.files.uploads).sort(([a], [b]) => a.localeCompare(b))
@@ -49,7 +49,7 @@ const FileUploadList = () => {
                     </Tooltip>
                     <Code className={'flex-1 truncate'}>{name}</Code>
                     <button
-                        onClick={removeFileUpload.bind(this, name)}
+                        onClick={cancelFileUpload.bind(this, name)}
                         className={'text-gray-500 hover:text-gray-200 transition-colors duration-75'}
                     >
                         <XIcon className={'w-5 h-5'} />
diff --git a/resources/scripts/components/server/files/UploadButton.tsx b/resources/scripts/components/server/files/UploadButton.tsx
index c5cac0e2..9ab889b8 100644
--- a/resources/scripts/components/server/files/UploadButton.tsx
+++ b/resources/scripts/components/server/files/UploadButton.tsx
@@ -59,9 +59,6 @@ export default ({ className }: WithClassname) => {
 
     const onUploadProgress = (data: ProgressEvent, name: string) => {
         setUploadProgress({ name, loaded: data.loaded });
-        if (data.loaded >= data.total) {
-            timeouts.value.push(setTimeout(() => removeFileUpload(name), 500));
-        }
     };
 
     const onFileSubmission = (files: FileList) => {
@@ -73,20 +70,25 @@ export default ({ className }: WithClassname) => {
 
         const uploads = list.map((file) => {
             const controller = new AbortController();
-            pushFileUpload({ name: file.name, data: { abort: controller, loaded: 0, total: file.size } });
+            pushFileUpload({
+                name: file.name,
+                data: { abort: controller, loaded: 0, total: file.size },
+            });
 
             return () =>
                 getFileUploadUrl(uuid).then((url) =>
-                    axios.post(
-                        url,
-                        { files: file },
-                        {
-                            signal: controller.signal,
-                            headers: { 'Content-Type': 'multipart/form-data' },
-                            params: { directory },
-                            onUploadProgress: (data) => onUploadProgress(data, file.name),
-                        }
-                    )
+                    axios
+                        .post(
+                            url,
+                            { files: file },
+                            {
+                                signal: controller.signal,
+                                headers: { 'Content-Type': 'multipart/form-data' },
+                                params: { directory },
+                                onUploadProgress: (data) => onUploadProgress(data, file.name),
+                            }
+                        )
+                        .then(() => timeouts.value.push(setTimeout(() => removeFileUpload(file.name), 500)))
                 );
         });
 
diff --git a/resources/scripts/state/server/files.ts b/resources/scripts/state/server/files.ts
index 7e4786ae..175c3d35 100644
--- a/resources/scripts/state/server/files.ts
+++ b/resources/scripts/state/server/files.ts
@@ -21,6 +21,7 @@ export interface ServerFileStore {
     setUploadProgress: Action<ServerFileStore, { name: string; loaded: number }>;
     clearFileUploads: Action<ServerFileStore>;
     removeFileUpload: Action<ServerFileStore, string>;
+    cancelFileUpload: Action<ServerFileStore, string>;
 }
 
 const files: ServerFileStore = {
@@ -61,6 +62,12 @@ const files: ServerFileStore = {
     }),
 
     removeFileUpload: action((state, payload) => {
+        if (state.uploads[payload]) {
+            delete state.uploads[payload];
+        }
+    }),
+
+    cancelFileUpload: action((state, payload) => {
         if (state.uploads[payload]) {
             // Abort the request if it is still in flight. If it already completed this is
             // a no-op.