// The converter form: sends the address to /api/convert (rekopub-web) and // shows the download links on this page. Without this script the form still // works, and the server answers with a page of its own. (function () { "use strict"; var form = document.getElementById("convert-form"); var fields = document.getElementById("convert-fields"); var result = document.getElementById("convert-result"); var keepHours = document.getElementById("keep-hours"); var button = form.querySelector("button"); if (!window.fetch || !window.URLSearchParams) return; function el(tag, attrs, text) { var node = document.createElement(tag); for (var k in attrs) node.setAttribute(k, attrs[k]); if (text) node.textContent = text; return node; } function show(nodes) { result.replaceChildren.apply(result, nodes); } function message(text, isError) { show([el("p", isError ? { "class": "convert-error" } : {}, text)]); } function hours(n) { return n === 1 ? "1 hour" : n + " hours"; } // pause disables the form while conversions are paused. function pause(text) { fields.disabled = true; message(text, true); } function size(bytes) { return bytes < 1024 * 1024 ? Math.ceil(bytes / 1024) + " KB" : (bytes / 1024 / 1024).toFixed(1) + " MB"; } // The server's reply, or a stand-in when nginx answered instead (a // limit, a timeout or the converter being down). function readReply(res) { return res.json().catch(function () { if (res.status === 429) return { error: "Too many requests at once. Please wait a minute and try again." }; if (res.status === 503) return { error: "The converter is busy. Please try again in a minute." }; if (res.status === 504) return { error: "That page took too long to convert." }; return { error: "The converter isn't available right now. Please try again later." }; }); } fetch("/api/status", { headers: { Accept: "application/json" } }) .then(readReply) .then(function (st) { if (st.keepHours) keepHours.textContent = st.keepHours; if (st.paused) pause(st.error); }) .catch(function () {}); form.addEventListener("submit", function (event) { event.preventDefault(); var body = new URLSearchParams(new FormData(form)); fields.disabled = true; button.textContent = "Converting…"; message("Converting… this can take up to a minute."); fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body: body }) .then(readReply) .then(function (rep) { fields.disabled = false; button.textContent = "Convert"; if (rep.paused) return pause(rep.error); if (rep.error) return message(rep.error, true); var list = el("ul", { "class": "convert-files" }); rep.files.forEach(function (f) { var li = el("li"); li.append(el("a", { href: f.url, download: "" }, f.name), " ", el("span", { "class": "small" }, f.format + ", " + size(f.size))); list.append(li); }); var nodes = [el("p", { "class": "small" }, "Links work for " + hours(rep.keepHours) + "."), list]; if (rep.warning) nodes.push(el("p", { "class": "convert-error" }, rep.warning)); show(nodes); }) .catch(function () { fields.disabled = false; button.textContent = "Convert"; message("Couldn't reach the converter. Check your connection and try again.", true); }); }); })();