Browse Source

Move file upload logic to HTTP and DAV

This also returns handleFileUpload file to original state
Aleksei Shpakovskii 2 years ago
parent
commit
947cafa483
3 changed files with 44 additions and 49 deletions
  1. 27 8
      src/lib/DAV.ts
  2. 13 2
      src/lib/HTTP.ts
  3. 4 39
      src/lib/handleFileUpload.ts

+ 27 - 8
src/lib/DAV.ts

@@ -299,19 +299,38 @@ export class DAV {
   /**
    * @param path The path to upload the file to
    * @param file The File object to upload
+   * @param onProgress function to call every time a chunk of data is uploaded
    */
-  async upload(path: string, file: File): Promise<Response> {
+  async upload(
+    path: string,
+    file: File,
+    onProgress: (uploadedBytes: number) => void = () => {}
+  ): Promise<{ ok: boolean }> {
     const targetFile = joinPath(path, file.name);
 
-    return this.#toastOnFailure(
-      (): Promise<Response> =>
-        this.#http.PUT(targetFile, {
-          headers: {
-            'Content-Type': file.type,
+    const xhr = await this.#http.PUT(
+      joinPath(location.pathname, file.name),
+      file,
+      onProgress
+    );
+
+    const ok = xhr.status >= 200 && xhr.status < 300;
+
+    if (!ok) {
+      error(
+        t('failure', {
+          interpolation: {
+            escapeValue: false,
           },
-          body: file,
+          method: 'PUT',
+          url: xhr.responseURL,
+          statusText: xhr.statusText,
+          status: xhr.status,
         })
-    );
+      );
+    }
+
+    return { ok: ok };
   }
 }
 

+ 13 - 2
src/lib/HTTP.ts

@@ -60,8 +60,19 @@ export class HTTP {
     return method('HEAD', url, parameters);
   }
 
-  PUT(url: string, parameters: RequestInit = {}): Promise<Response> {
-    return method('PUT', url, parameters);
+  PUT(
+    url: string,
+    file: File,
+    onProgress: (uploadedBytes: number) => void
+  ): Promise<XMLHttpRequest> {
+    return new Promise((resolve) => {
+      const xhr = new XMLHttpRequest();
+      xhr.open('PUT', url, true);
+      xhr.setRequestHeader('Content-Type', file.type);
+      xhr.upload.onprogress = (e) => onProgress(e.loaded);
+      xhr.onloadend = () => resolve(xhr);
+      xhr.send(file);
+    });
   }
 
   PROPFIND(url: string, parameters: RequestInit = {}): Promise<Response> {

+ 4 - 39
src/lib/handleFileUpload.ts

@@ -2,24 +2,9 @@ import DAV from './DAV';
 import Entry from './Entry';
 import State from './State';
 import joinPath from './joinPath';
-import { success, error } from 'melba-toast';
+import { success } from 'melba-toast';
 import { t } from 'i18next';
 
-const XHRPutFile = (
-  url: string,
-  file: File,
-  onProgress: (progress: number) => void
-): Promise<XMLHttpRequest> => {
-  return new Promise((resolve, reject) => {
-    const xhr = new XMLHttpRequest();
-    xhr.upload.onprogress = (e) => onProgress(e.loaded);
-    xhr.onloadend = () => resolve(xhr);
-    xhr.open('PUT', url, true);
-    xhr.setRequestHeader('Content-Type', file.type);
-    xhr.send(file);
-  });
-};
-
 export const handleFileUpload = async (
   dav: DAV,
   state: State,
@@ -63,32 +48,12 @@ export const handleFileUpload = async (
 
   collection.add(placeholder);
 
-  const xhr = await XHRPutFile(
-    joinPath(location.pathname, file.name),
-    file,
-    (uploaded: number) => {
-      placeholder.uploadedSize = uploaded;
-      placeholder.emit('updated');
-    }
-  );
-
-  const ok = xhr.status >= 200 && xhr.status < 300;
+  const result = await dav.upload(location.pathname, file);
 
-  if (!ok) {
+  if (!result.ok) {
     collection.remove(placeholder);
-    state.update();
 
-    error(
-      t('failure', {
-        interpolation: {
-          escapeValue: false,
-        },
-        method: 'PUT',
-        url: xhr.responseURL,
-        statusText: xhr.statusText,
-        status: xhr.status,
-      })
-    );
+    state.update();
 
     return;
   }