const Authentication = require('./authentication') const lang = require('./lang') function safeParseReponse(str, status, url) { if (status === 0) { return new Error(lang.api_down) } if (str.slice(0, 9) === '= 300) { if (out.message) { throw out } console.error('Got error ' + xhr.status + ' but no error message:', out) throw new Error('Unknown or empty response from server.') } if (pagination) { let headers = {} xhr.getAllResponseHeaders().split('\r\n').forEach(function(item) { let splitted = item.split(': ') headers[splitted[0]] = splitted[1] }) out = { headers: headers || {}, data: out, } } return out } return m.request(options) .then(function(res) { api.loading = false window.requestAnimationFrame(m.redraw.bind(m)) return res }) .catch(function (error) { api.loading = false window.requestAnimationFrame(m.redraw.bind(m)) if (error.status === 403) { Authentication.clearToken() m.route.set('/', { redirect: m.route.get() }) } if (error.response && error.response.status) { return Promise.reject(error.response) } return Promise.reject(error) }) }, prettyFormatBytes: function(bytes) { if (bytes < 1024) { return `${bytes} B` } if (bytes < 1024 * 1024) { return `${(bytes / 1024).toFixed(1)} KB` } if (bytes < 1024 * 1024 * 1024) { return `${(bytes / 1024 / 1024).toFixed(1)} MB` } }, uploadFileProgress: function(options, file, reporter) { api.loading = true return new Promise(function(res, rej) { let report = reporter || function() {} let formdata = new FormData() formdata.append('file', file) let request = new XMLHttpRequest() let finished = false let lastMarker = new Date() let lastMarkerLoaded = 0 let lastMarkerSpeed = '...' request.abortRequest = function() { finished = true request.abort() } request.upload.addEventListener('progress', function (e) { let check = new Date() if (check - lastMarker >= 1000) { let loaded = e.loaded - lastMarkerLoaded lastMarkerSpeed = api.prettyFormatBytes(loaded / ((check - lastMarker) / 1000)) lastMarker = check lastMarkerLoaded = e.loaded } report(request, Math.min(e.loaded / file.size * 100, 100), lastMarkerSpeed) }) request.addEventListener('abort', function(e) { finished = true window.requestAnimationFrame(m.redraw.bind(m)) rej() }) request.addEventListener('readystatechange', function(e) { if (finished) return if (request.readyState !== 4) return finished = true let out = safeParseReponse(request.responseText, request.status, options.url) if (out instanceof Error || request.status >= 300) { return rej(out) } return res(out) }) request.open(options.method || 'POST', options.url) request.send(formdata) report(request, 0) }) .then(function(res) { api.loading = false window.requestAnimationFrame(m.redraw.bind(m)) return res }, function(err) { api.loading = false window.requestAnimationFrame(m.redraw.bind(m)) return Promise.reject(err) }) }, } module.exports = api