From f34acf76274674fedf492e1425a0009a39fc526c Mon Sep 17 00:00:00 2001 From: bohwaz Date: Tue, 22 Nov 2022 03:40:49 +0100 Subject: [PATCH] Add progress bar to download of all files --- index.php | 111 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 23 deletions(-) diff --git a/index.php b/index.php index 51f8d42..2362ab3 100644 --- a/index.php +++ b/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) => { `; const dir_row_tpl = `%icon%%name%%modified%
`; - const file_row_tpl = `%icon%%name%%size%%modified%
${_('Download')}
`; + const file_row_tpl = `%icon%%name%%size_bytes%%modified%
${_('Download')}
`; const propfind_tpl = ` @@ -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(`

${html(name)}

`, 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, ' ') : null; + item.size_bytes = item.size !== null ? formatBytes(item.size).replace(/ /g, ' ') : null; item.icon = item.is_dir ? '📁' : (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) {