diff --git a/filadelfia_archive/app/api.js b/filadelfia_archive/app/api.js index 4360d63..a92848b 100644 --- a/filadelfia_archive/app/api.js +++ b/filadelfia_archive/app/api.js @@ -21,9 +21,22 @@ function safeParseReponse(str, status, url) { } } +let requests = new Set() +let requestIndex = 0 + +function clearLoading(request) { + requests.delete(request) + if (!requests.size) { + api.loading = false + window.requestAnimationFrame(m.redraw.bind(m)) + } +} + const api = { loading: false, sendRequest: function(options, isPagination) { + let request = requestIndex++ + requests.add(request) api.loading = true let token = Authentication.getToken() let pagination = isPagination @@ -61,15 +74,14 @@ const api = { } return out } - + return m.request(options) .then(function(res) { - api.loading = false - window.requestAnimationFrame(m.redraw.bind(m)) + clearLoading(request) return res }) .catch(function (error) { - api.loading = false + clearLoading(request) window.requestAnimationFrame(m.redraw.bind(m)) if (error.status === 403) { Authentication.clearToken() @@ -82,10 +94,15 @@ const api = { }) }, - uploadBanner: function(bannerFile, token) { + uploadBanner: function(bannerFile, token, reporter) { + let request = requestIndex++ + requests.add(request) + api.loading = true + + var report = reporter || function() {} var data = new FormData() data.append('file', bannerFile) - data.append('preview', JSON.stringify({ + /*data.append('preview', JSON.stringify({ "out": "base64", "format": "avif", "resize": { @@ -96,10 +113,10 @@ const api = { "kernel": "mitchell" }, "avif": { - "quality": 50, + "quality": 40, "effort": 9 } - })) + }))*/ data.append('medium', JSON.stringify({ "format": "avif", "resize": { @@ -115,29 +132,75 @@ const api = { } })) + report(lang.api_banner_upload) + return api.sendRequest({ method: 'POST', url: token.resize + '?token=' + token.token, body: data, }) - .then(banner => { + .then(async (banner) => { + let preview = null + let quality = 60 + while (!preview && quality > 10) { + report(lang.format(lang.api_banner_generate, quality)) + let check = await api.sendRequest({ + method: 'POST', + url: token.resize + '/' + banner.filename + '?token=' + token.token, + body: { + "preview": { + "out": "base64", + "format": "avif", + "resize": { + "width": 360, + "height": 203, + "fit": "cover", + "withoutEnlargement": true, + "kernel": "mitchell" + }, + "avif": { + "quality": quality, + "effort": 9 + } + }, + }, + }) + + if (check.preview.base64.length < 8000) { + preview = check.preview.base64 + } else { + quality -= 5 + } + } + report(null) + api.sendRequest({ method: 'DELETE', url: token.delete + banner.filename + '?token=' + token.token, }).catch(err => console.error(err)) return { - file: banner, + file: bannerFile, size: bannerFile.size, medium: { filename: banner.medium.filename, path: banner.medium.path, }, preview: { - base64: banner.preview.base64, + base64: preview, }, } }) + .then( + function(res) { + clearLoading(request) + return res + }, + function(err) { + clearLoading(request) + return Promise.reject(err) + } + ) }, prettyFormatBytes: function(bytes) { @@ -153,6 +216,8 @@ const api = { }, uploadFileProgress: function(options, file, reporter) { + let request = requestIndex++ + requests.add(request) api.loading = true return new Promise(function(res, rej) { @@ -207,12 +272,10 @@ const api = { report(request, 0) }) .then(function(res) { - api.loading = false - window.requestAnimationFrame(m.redraw.bind(m)) + clearLoading(request) return res }, function(err) { - api.loading = false - window.requestAnimationFrame(m.redraw.bind(m)) + clearLoading(request) return Promise.reject(err) }) }, diff --git a/filadelfia_archive/app/lang.js b/filadelfia_archive/app/lang.js index fdb6f1a..e3ef589 100644 --- a/filadelfia_archive/app/lang.js +++ b/filadelfia_archive/app/lang.js @@ -59,6 +59,10 @@ const i18n = { 'Villa við að eyða efni: {0}'], article_error: ['Error while saving: {0}', 'Villa við að vista: {0}'], + api_banner_upload: ['Uploading banner image', + 'Er að senda mynd'], + api_banner_generate:['Generating preview, testing quality {0}%', + 'Bý til forsíðumynd, prufa {0}% gæði'], months: { '1': ['January', 'Janúar'], diff --git a/filadelfia_archive/app/page_upload.js b/filadelfia_archive/app/page_upload.js index f9606d7..469abb3 100644 --- a/filadelfia_archive/app/page_upload.js +++ b/filadelfia_archive/app/page_upload.js @@ -19,6 +19,7 @@ const Upload = { this.cacheVideo = null this.cacheImage = null this.uploading = null + this.bannerStatus = null this.form = { title: 'Sunnudagssamkoma', date: d, @@ -49,7 +50,10 @@ const Upload = { return this.cacheImage } - return api.uploadBanner(this.form.banner, res) + return api.uploadBanner(this.form.banner, res, (status) => { + this.bannerStatus = status + m.redraw() + }) .then(imageData => { this.cacheImage = imageData return res @@ -113,6 +117,7 @@ const Upload = { m.route.set('/') }) .catch((error) => { + this.bannerStatus = null this.uploading = null if (!error) return @@ -196,6 +201,10 @@ const Upload = { value: 'Begin upload', }), api.loading ? m('div.loading-spinner') : null, + this.bannerStatus ? [ + m('p', this.bannerStatus), + m('.loading-bar', { style: `--progress: 0%` }), + ] : null, this.uploading ? [ m('p', `${Math.floor(this.uploading.progress)}% (${this.uploading.perSecond}/s)`), m('.loading-bar', { style: `--progress: ${this.uploading.progress}%` }), diff --git a/filadelfia_archive/package.json b/filadelfia_archive/package.json index 3545eb6..d01aa17 100644 --- a/filadelfia_archive/package.json +++ b/filadelfia_archive/package.json @@ -1,6 +1,6 @@ { "name": "filadelfia_archive", - "version": "1.0.4", + "version": "1.0.5", "port": 4130, "description": "Filadelfia archive", "main": "index.js", diff --git a/filadelfia_archive/public/index.html b/filadelfia_archive/public/index.html index 5abe792..3e9cfc4 100644 --- a/filadelfia_archive/public/index.html +++ b/filadelfia_archive/public/index.html @@ -145,7 +145,6 @@ footer a { font-size: 0.8rem; } .article { width: 100%; max-width: 1280px; padding: 0.5rem; align-self: center; margin-bottom: 5rem; } .article .full-error { margin-top: 1rem; } .article-name { flex: 2 1 auto; margin-left: 1rem; } -.image-banner { height: 160px; } .article h1 { margin: 0; } .article h1, .article p { padding: 0 0.5rem 0.5rem; }