diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2023-03-01 22:59:41 -0400 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2023-03-01 22:59:41 -0400 |
commit | 8b9e855c57c8879934f9ccc8fa17f73966465a17 (patch) | |
tree | 9b72d98c500fecca903483722a9d8fe242757da2 /src/static/client.js | |
parent | 0f7e9e5dfb429b14b816370dc1472ee4c2ae82eb (diff) |
image overlay download progress bar
Diffstat (limited to 'src/static/client.js')
-rw-r--r-- | src/static/client.js | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/src/static/client.js b/src/static/client.js index addc93a4..5b8b0c8a 100644 --- a/src/static/client.js +++ b/src/static/client.js @@ -677,17 +677,30 @@ function handleImageLinkClicked(evt) { const mainThumbSize = getPreferredThumbSize(); const source = evt.target.closest('a').href; - mainImage.src = source.replace(/\.(jpg|png)$/, `.${mainThumbSize}.jpg`); - thumbImage.src = source.replace(/\.(jpg|png)$/, '.small.jpg'); + + const mainSrc = source.replace(/\.(jpg|png)$/, `.${mainThumbSize}.jpg`); + const thumbSrc = source.replace(/\.(jpg|png)$/, '.small.jpg'); + + thumbImage.src = thumbSrc; for (const viewOriginal of allViewOriginal) { viewOriginal.href = source; } + mainImage.addEventListener('load', handleMainImageLoaded); + mainImage.addEventListener('error', handleMainImageErrored); + const fileSize = evt.target.closest('a').querySelector('img').dataset.originalSize; updateFileSizeInformation(fileSize); - mainImage.addEventListener('load', handleMainImageLoaded); - mainImage.addEventListener('error', handleMainImageErrored); + container.style.setProperty('--download-progress', '0%'); + loadImage(mainSrc, progress => { + container.style.setProperty('--download-progress', (20 + 0.8 * progress) + '%'); + }).then( + blobUrl => { + mainImage.src = blobUrl; + container.style.setProperty('--download-progress', '100%'); + }, + handleMainImageErrored); function handleMainImageLoaded() { mainImage.removeEventListener('load', handleMainImageLoaded); @@ -770,3 +783,64 @@ function updateFileSizeInformation(fileSize) { } addImageOverlayClickHandlers(); + +/** + * Credits: Parziphal, Feb 13, 2017 + * https://stackoverflow.com/a/42196770 + * + * Loads an image with progress callback. + * + * The `onprogress` callback will be called by XMLHttpRequest's onprogress + * event, and will receive the loading progress ratio as an whole number. + * However, if it's not possible to compute the progress ratio, `onprogress` + * will be called only once passing -1 as progress value. This is useful to, + * for example, change the progress animation to an undefined animation. + * + * @param {string} imageUrl The image to load + * @param {Function} onprogress + * @return {Promise} + */ +function loadImage(imageUrl, onprogress) { + return new Promise((resolve, reject) => { + var xhr = new XMLHttpRequest(); + var notifiedNotComputable = false; + + xhr.open('GET', imageUrl, true); + xhr.responseType = 'arraybuffer'; + + xhr.onprogress = function(ev) { + if (ev.lengthComputable) { + onprogress(parseInt((ev.loaded / ev.total) * 1000) / 10); + } else { + if (!notifiedNotComputable) { + notifiedNotComputable = true; + onprogress(-1); + } + } + } + + xhr.onloadend = function() { + if (!xhr.status.toString().match(/^2/)) { + reject(xhr); + } else { + if (!notifiedNotComputable) { + onprogress(100); + } + + var options = {} + var headers = xhr.getAllResponseHeaders(); + var m = headers.match(/^Content-Type:\s*(.*?)$/mi); + + if (m && m[1]) { + options.type = m[1]; + } + + var blob = new Blob([this.response], options); + + resolve(window.URL.createObjectURL(blob)); + } + } + + xhr.send(); + }); +} |