Browse Source

Add progress bar to download of all files

bohwaz 2 years ago
parent
commit
f34acf7627
1 changed files with 88 additions and 23 deletions
  1. 88 23
      index.php

+ 88 - 23
index.php

@@ -1852,11 +1852,11 @@ RewriteRule ^.*$ /index.php [END]
 
 		if ($relative_uri == '.webdav/webdav.js') {
 			fseek($fp, 49805, SEEK_SET);
-			echo fread($fp, 26310);
+			echo fread($fp, 27579);
 		}
 		else {
-			fseek($fp, 49805 + 26310, SEEK_SET);
-			echo fread($fp, 6760);
+			fseek($fp, 49805 + 27579, SEEK_SET);
+			echo fread($fp, 6801);
 		}
 
 		fclose($fp);
@@ -1989,7 +1989,7 @@ const WebDAVNavigator = (url, options) => {
 			<input class="uploadfile" type="button" value="${_('Upload file')}" />`;
 
 	const dir_row_tpl = `<tr data-permissions="%permissions%"><td class="thumb"><span class="icon dir"><b>%icon%</b></span></td><th colspan="2"><a href="%uri%">%name%</a></th><td>%modified%</td><td class="buttons"><div></div></td></tr>`;
-	const file_row_tpl = `<tr data-permissions="%permissions%" data-mime="%mime%"><td class="thumb"><span class="icon %icon%"><b>%icon%</b></span></td><th><a href="%uri%">%name%</a></th><td class="size">%size%</td><td>%modified%</td><td class="buttons"><div><a href="%uri%" download class="btn">${_('Download')}</a></div></td></tr>`;
+	const file_row_tpl = `<tr data-permissions="%permissions%" data-mime="%mime%" data-size="%size%"><td class="thumb"><span class="icon %icon%"><b>%icon%</b></span></td><th><a href="%uri%">%name%</a></th><td class="size">%size_bytes%</td><td>%modified%</td><td class="buttons"><div><a href="%uri%" download class="btn">${_('Download')}</a></div></td></tr>`;
 
 	const propfind_tpl = `<?xml version="1.0" encoding="UTF-8"?>
 		<D:propfind xmlns:D="DAV:" xmlns:oc="http://owncloud.org/ns">
@@ -2039,17 +2039,6 @@ const WebDAVNavigator = (url, options) => {
 		return false;
 	};
 
-	const get_url = async (url) => {
-		if (temp_object_url) {
-			window.URL.revokeObjectURL(temp_object_url);
-		}
-
-		return req('GET', url).then(r => r.blob()).then(blob => {
-			temp_object_url = window.URL.createObjectURL(blob);
-			return temp_object_url;
-		});
-	}
-
 	const req = (method, url, body, headers) => {
 		if (!headers) {
 			headers = {};
@@ -2062,6 +2051,51 @@ const WebDAVNavigator = (url, options) => {
 		return fetch(url, {method, body, headers});
 	};
 
+	const xhr = (method, url, progress_callback) => {
+		var xhr = new XMLHttpRequest();
+		current_xhr = xhr;
+		xhr.responseType = 'blob';
+		var p = new Promise((resolve, reject) => {
+			xhr.open(method, url);
+			xhr.onload = function () {
+				if (this.status >= 200 && this.status < 300) {
+					resolve(xhr.response);
+				} else {
+					reject({
+						status: this.status,
+						statusText: xhr.statusText
+					});
+				}
+			};
+			xhr.onerror = function () {
+				reject({
+					status: this.status,
+					statusText: xhr.statusText
+				});
+			};
+			xhr.onprogress = progress_callback;
+			xhr.send();
+		});
+		return p;
+	};
+
+	const get_url = async (url) => {
+		var progress = (e) => {
+			var p = $('progress');
+			if (!p) return;
+			p.value = e.loaded;
+		};
+
+		if (temp_object_url) {
+			window.URL.revokeObjectURL(temp_object_url);
+		}
+
+		return await xhr('GET', url, progress).then(blob => {
+			temp_object_url = window.URL.createObjectURL(blob);
+			return temp_object_url;
+		});
+	};
+
 	const wopi_init = async () => {
 		if (!wopi_discovery_url) {
 			return;
@@ -2163,6 +2197,17 @@ const WebDAVNavigator = (url, options) => {
 	};
 
 	const closeDialog = (e) => {
+		if (!$('body').classList.contains('dialog')) {
+			return;
+		}
+
+		if (current_xhr) {
+			current_xhr.abort();
+			current_xhr = null;
+		}
+
+		window.onbeforeunload = null;
+
 		$('body').classList.remove('dialog');
 		if (!$('dialog')) return;
 		$('dialog').remove();
@@ -2170,16 +2215,29 @@ const WebDAVNavigator = (url, options) => {
 		evt = null;
 	};
 
-	const download = async (name, url) => {
-		var url = await get_url(url);
+	const download = async (name, size, url) => {
+		window.onbeforeunload = () => {
+			if (current_xhr) {
+				current_xhr.abort();
+			}
+
+			return true;
+		};
+
+		openDialog(`<h3>${html(name)}</h3><progress max="${size}"></progress>`, false);
+
+		await get_url(url);
 		const a = document.createElement('a');
 		a.style.display = 'none';
-		a.href = url;
+		a.href = temp_object_url;
 		a.download = name;
 		document.body.appendChild(a);
 		a.click();
-		window.URL.revokeObjectURL(url);
+		window.URL.revokeObjectURL(temp_object_url);
 		a.remove();
+
+		closeDialog();
+		window.onbeforeunload = null;
 	};
 
 	const download_all = async () => {
@@ -2189,7 +2247,7 @@ const WebDAVNavigator = (url, options) => {
 				continue;
 			}
 
-			await download(item.name, item.uri)
+			await download(item.name, item.size, item.uri)
 		}
 	};
 
@@ -2395,7 +2453,7 @@ const WebDAVNavigator = (url, options) => {
 			}
 
 			var row = item.is_dir ? dir_row_tpl : file_row_tpl;
-			item.size = item.size !== null ? formatBytes(item.size).replace(/ /g, '&nbsp;') : null;
+			item.size_bytes = item.size !== null ? formatBytes(item.size).replace(/ /g, '&nbsp;') : null;
 			item.icon = item.is_dir ? '&#x1F4C1;' : (item.uri.indexOf('.') > 0 ? item.uri.replace(/^.*\.(\w+)$/, '$1').toUpperCase() : '');
 			item.modified = item.modified !== null ? formatDate(item.modified) : null;
 			item.name = html(item.name);
@@ -2478,6 +2536,7 @@ const WebDAVNavigator = (url, options) => {
 			var mime = !dir ? tr.getAttribute('data-mime') : 'dir';
 			var buttons = $$('td.buttons div');
 			var permissions = tr.getAttribute('data-permissions');
+			var size = tr.getAttribute('data-size');
 
 			if (permissions == 'null') {
 				permissions = null;
@@ -2501,7 +2560,7 @@ const WebDAVNavigator = (url, options) => {
 			// This is to get around CORS when not on the same domain
 			if (user && password && (a = tr.querySelector('a[download]'))) {
 				a.onclick = () => {
-					download(file_name, url);
+					download(file_name, size, url);
 					return false;
 				};
 			}
@@ -2575,7 +2634,7 @@ const WebDAVNavigator = (url, options) => {
 				$$('a').onclick = () => { wopi_open(file_url, view_url); return false; };
 			}
 			else if (user && password && !dir) {
-				$$('a').onclick = () => { download(file_name, file_url); return false; };
+				$$('a').onclick = () => { download(file_name, size, file_url); return false; };
 			}
 			else {
 				$$('a').download = file_name;
@@ -2631,6 +2690,7 @@ const WebDAVNavigator = (url, options) => {
 	};
 
 	var items = [[], []];
+	var current_xhr = null;
 	var current_url = url;
 	var base_url = url;
 	const user = options.user || null;
@@ -3100,6 +3160,11 @@ dialog {
 	transition: all .3s;
 }
 
+progress {
+	height: 2em;
+	width: 90%;
+}
+
 @keyframes spin { to { transform: rotate(360deg); } }
 
 @media screen and (max-width: 800px) {