Prechádzať zdrojové kódy

allow cancelling push

Gildas 4 rokov pred
rodič
commit
54f7fc6e66

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

@@ -195,7 +195,7 @@ async function saveContent(message, tab) {
 					const blob = new Blob([pageData.content], { type: "text/html" });
 					await downloads.saveToGDrive(message.taskId, pageData.filename, blob, options, {}).uploadPromise;
 				} if (options.saveToGitHub) {
-					await downloads.saveToGitHub(pageData.filename, pageData.content, options.githubToken, options.githubUser, options.githubRepository, options.githubBranch);
+					await downloads.saveToGitHub(message.taskId, pageData.filename, pageData.content, options.githubToken, options.githubUser, options.githubRepository, options.githubBranch).pushPromise;
 				} else if (options.saveWithCompanion) {
 					await companion.save({
 						filename: pageData.filename,

+ 8 - 3
extension/core/bg/downloads.js

@@ -138,7 +138,7 @@ async function downloadContent(contents, tab, incognito, message) {
 				onProgress: (offset, size) => ui.onUploadProgress(tab.id, offset, size)
 			}).uploadPromise;
 		} else if (message.saveToGitHub) {
-			await saveToGitHub(message.filename, contents.join(""), message.githubToken, message.githubUser, message.githubRepository, message.githubBranch);
+			await saveToGitHub(message.taskId, message.filename, contents.join(""), message.githubToken, message.githubUser, message.githubRepository, message.githubBranch).pushPromise;
 		} else if (message.saveWithCompanion) {
 			await companion.save({
 				filename: message.filename,
@@ -202,8 +202,13 @@ async function getAuthInfo(authOptions, force) {
 	return authInfo;
 }
 
-function saveToGitHub(filename, content, githubToken, githubUser, githubRepository, githubBranch) {
-	return pushGitHub(githubToken, githubUser, githubRepository, githubBranch, filename, content);
+function saveToGitHub(taskId, filename, content, githubToken, githubUser, githubRepository, githubBranch) {
+	const taskInfo = business.getTaskInfo(taskId);
+	if (taskInfo && !taskInfo.cancelled) {
+		const pushInfo = pushGitHub(githubToken, githubUser, githubRepository, githubBranch, filename, content);
+		business.setCancelCallback(taskId, pushInfo.cancelPush);
+		return pushInfo;
+	}
 }
 
 async function saveToGDrive(taskId, filename, blob, authOptions, uploadOptions) {

+ 28 - 17
extension/lib/github/github.js

@@ -21,7 +21,7 @@
  *   Source.
  */
 
-/* global fetch, btoa */
+/* global fetch, btoa, AbortController */
 
 export { pushGitHub };
 
@@ -31,29 +31,40 @@ async function pushGitHub(token, userName, repositoryName, branchName, path, con
 	while (pendingPush) {
 		await pendingPush;
 	}
+	const controller = new AbortController();
 	pendingPush = async () => {
 		try {
-			await createContent({ path, content });
+			await createContent({ path, content }, controller.signal);
 		} finally {
 			pendingPush = null;
 		}
 	};
-	await pendingPush();
+	return {
+		cancelPush: () => controller.abort(),
+		pushPromise: pendingPush()
+	};
 
-	async function createContent({ path, content, message = "" }) {
-		const response = await fetch(`https://api.github.com/repos/${userName}/${repositoryName}/contents/${path}`, {
-			method: "PUT",
-			headers: new Map([
-				["Authorization", `token ${token}`],
-				["Accept", "application/vnd.github.v3+json"]
-			]),
-			body: JSON.stringify({ content: btoa(content), message, branch: branchName })
-		});
-		const responseData = await response.json();
-		if (response.status < 400) {
-			return responseData;
-		} else {
-			throw new Error(responseData.message);
+	async function createContent({ path, content, message = "" }, signal) {
+		try {
+			const response = await fetch(`https://api.github.com/repos/${userName}/${repositoryName}/contents/${path}`, {
+				method: "PUT",
+				headers: new Map([
+					["Authorization", `token ${token}`],
+					["Accept", "application/vnd.github.v3+json"]
+				]),
+				body: JSON.stringify({ content: btoa(unescape(encodeURIComponent(content))), message, branch: branchName }),
+				signal
+			});
+			const responseData = await response.json();
+			if (response.status < 400) {
+				return responseData;
+			} else {
+				throw new Error(responseData.message);
+			}
+		} catch (error) {
+			if (error.name != "AbortError") {
+				throw error;
+			}
 		}
 	}
 }