diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-05-15 18:12:45 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-05-15 18:12:45 -0300 |
commit | 25bc1e3391819f55fdd51a3313bea874b2db1e65 (patch) | |
tree | 3cbc96b6010196896a6ce53fcc87873628f7e000 | |
parent | 98964898cdff29cd6a93ba1ed255323d3028f789 (diff) |
client: fetchWithProgress
-rw-r--r-- | src/static/client4.js | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/static/client4.js b/src/static/client4.js index 64f5b377..02144e16 100644 --- a/src/static/client4.js +++ b/src/static/client4.js @@ -2840,6 +2840,69 @@ function updateFileSizeInformation(fileSize) { addImageOverlayClickHandlers(); /** + * This fetch function is adapted from a `loadImage` function + * credited to Parziphal, Feb 13, 2017. + * https://stackoverflow.com/a/42196770 + * + * The callback is generally run with the loading progress as a decimal 0-1. + * However, if it's not possible to compute the progress ration (which might + * only become apparent after a progress amount *has* been sent!), + * the callback will be run with the value -1. + * + * The return promise resolves to a manually instantiated Response object + * which generally behaves the same as a normal fetch response; access headers, + * text, blob, arrayBuffer as usual. Accordingly, non-200 responses do *not* + * reject the prmoise, so be sure to check the response status yourself. + */ +function fetchWithProgress(url, progressCallback) { + return new Promise(resolve => { + const xhr = new XMLHttpRequest(); + let notifiedNotComputable = false; + + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + + xhr.onprogress = event => { + if (notifiedNotComputable) { + return; + } + + if (!event.lengthComputable) { + notifiedNotComputable = true; + progressCallback(-1); + return; + } + + progressCallback(event.loaded / event.total); + }; + + xhr.onloadend = () => { + const body = xhr.response; + + const options = { + status: xhr.status, + headers: + parseResponseHeaders(xhr.getAllResponseHeaders()), + }; + + resolve(new Response(body, options)); + }; + + xhr.send(); + }); + + function parseResponseHeaders(headers) { + return ( + Object.fromEntries( + headers + .trim() + .split(/[\r\n]+/) + .map(line => line.match(/(.+?):\s*(.+)/)) + .map(match => [match[1], match[2]]))); + } +} + +/** * Credits: Parziphal, Feb 13, 2017 * https://stackoverflow.com/a/42196770 * |