Переглянути джерело

added support of cancellable uploads

Former-commit-id: 7d0ecdfad85d8b78121f1725c3577fe1466d5434
Gildas 6 роки тому
батько
коміт
73909e5a5b

+ 1 - 1
extension/core/bg/autosave.js

@@ -125,7 +125,7 @@ singlefile.extension.core.bg.autosave = (() => {
 		try {
 			const blob = new Blob([pageData.content], { type: "text/html" });
 			if (options.saveToGDrive) {
-				await singlefile.extension.core.bg.downloads.uploadPage(pageData.filename, blob, options, {});
+				await singlefile.extension.core.bg.downloads.uploadPage(tab.id, pageData.filename, blob, options, {});
 			} else {
 				pageData.url = URL.createObjectURL(blob);
 				await singlefile.extension.core.bg.downloads.downloadPage(pageData, options);

+ 15 - 5
extension/core/bg/business.js

@@ -51,7 +51,14 @@ singlefile.extension.core.bg.business = (() => {
 		saveTabs,
 		saveLink,
 		cancelTab,
-		getInfo: () => ({ pending: Array.from(pendingSaves).map(mapSaveInfo), processing: Array.from(currentSaves).map(mapSaveInfo) })
+		getTabsInfo: () => ({ pending: Array.from(pendingSaves).map(mapSaveInfo), processing: Array.from(currentSaves).map(mapSaveInfo) }),
+		getTabInfo: tabId => currentSaves.get(tabId) || pendingSaves.get(tabId),
+		setCancelCallback: (tabId, cancelCallback) => {
+			const tabInfo = currentSaves.get(tabId);
+			if (tabInfo) {
+				tabInfo.cancel = cancelCallback;
+			}
+		}
 	};
 
 	async function saveTabs(tabs, options = {}) {
@@ -106,14 +113,17 @@ singlefile.extension.core.bg.business = (() => {
 	async function cancelTab(tabId) {
 		try {
 			if (currentSaves.has(tabId)) {
-				const data = currentSaves.get(tabId);
-				data.cancelled = true;
+				const saveInfo = currentSaves.get(tabId);
+				saveInfo.cancelled = true;
 				singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: "content.cancelSave" });
+				if (saveInfo.cancel) {
+					saveInfo.cancel();
+				}
 			}
 			if (pendingSaves.has(tabId)) {
-				const data = pendingSaves.get(tabId);
+				const saveInfo = pendingSaves.get(tabId);
 				pendingSaves.delete(tabId);
-				singlefile.extension.ui.bg.main.onCancelled(data.tab);
+				singlefile.extension.ui.bg.main.onCancelled(saveInfo.tab);
 			}
 		} catch (error) {
 			// ignored

+ 15 - 7
extension/core/bg/downloads.js

@@ -66,7 +66,7 @@ singlefile.extension.core.bg.downloads = (() => {
 			return {};
 		}
 		if (message.method.endsWith(".getInfo")) {
-			return singlefile.extension.core.bg.business.getInfo();
+			return singlefile.extension.core.bg.business.getTabsInfo();
 		}
 		if (message.method.endsWith(".cancel")) {
 			await singlefile.extension.core.bg.business.cancelTab(message.tabId);
@@ -110,7 +110,7 @@ singlefile.extension.core.bg.downloads = (() => {
 					const blob = new Blob([contents], { type: MIMETYPE_HTML });
 					try {
 						if (message.saveToGDrive) {
-							await uploadPage(message.filename, blob, {
+							await uploadPage(tab.id, message.filename, blob, {
 								forceWebAuthFlow: message.forceWebAuthFlow,
 								extractAuthCode: message.extractAuthCode
 							}, {
@@ -127,8 +127,12 @@ singlefile.extension.core.bg.downloads = (() => {
 						}
 						singlefile.extension.ui.bg.main.onEnd(tab.id);
 					} catch (error) {
-						console.error(error); // eslint-disable-line no-console
-						singlefile.extension.ui.bg.main.onError(tab.id);
+						if (error.message && error.message == "upload_cancelled") {
+							await singlefile.extension.core.bg.business.cancelTab(tab.id);
+						} else {
+							console.error(error); // eslint-disable-line no-console
+							singlefile.extension.ui.bg.main.onError(tab.id);
+						}
 					} finally {
 						if (message.url) {
 							URL.revokeObjectURL(message.url);
@@ -163,10 +167,14 @@ singlefile.extension.core.bg.downloads = (() => {
 		return authInfo;
 	}
 
-	async function uploadPage(filename, blob, authOptions, uploadOptions) {
+	async function uploadPage(tabId, filename, blob, authOptions, uploadOptions) {
 		try {
 			await getAuthInfo(authOptions);
-			await gDrive.upload(filename, blob, uploadOptions);
+			if (!singlefile.extension.core.bg.business.getTabInfo(tabId).cancelled) {
+				const uploadInfo = await gDrive.upload(filename, blob, uploadOptions);
+				singlefile.extension.core.bg.business.setCancelCallback(tabId, uploadInfo.cancelUpload);
+				return await uploadInfo.uploadPromise;
+			}
 		}
 		catch (error) {
 			if (error.message == "invalid_token") {
@@ -185,7 +193,7 @@ singlefile.extension.core.bg.downloads = (() => {
 				} else {
 					await singlefile.extension.core.bg.config.removeAuthInfo();
 				}
-				await uploadPage(filename, blob, authOptions, uploadOptions);
+				await uploadPage(tabId, filename, blob, authOptions, uploadOptions);
 			} else {
 				throw error;
 			}

+ 9 - 2
extension/lib/gdrive/gdrive.js

@@ -137,7 +137,10 @@ this.GDrive = this.GDrive || (() => {
 				onProgress: options.onProgress
 			});
 			try {
-				return await uploader.upload();
+				return {
+					cancelUpload: () => uploader.cancelled = true,
+					uploadPromise: uploader.upload()
+				};
 			}
 			catch (error) {
 				if (error.message == "path_not_found" && retry) {
@@ -352,7 +355,11 @@ this.GDrive = this.GDrive || (() => {
 			if (range) {
 				mediaUploader.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1;
 			}
-			return sendFile(mediaUploader);
+			if (mediaUploader.cancelled) {
+				throw new Error("upload_cancelled");
+			} else {
+				return sendFile(mediaUploader);
+			}
 		} else {
 			getResponse(httpResponse);
 		}