v0.2.91
This commit is contained in:
1 parent
4da41a1404
commit
5cb6960b04
31 files changed
+1611
-2123
No files matched your search
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Mateusz Gruszczyński @linuxiarz.pl
|
||||
* Source-Available Code / Dual-Licensed.
|
||||
*
|
||||
* Free for non-commercial and evaluation use under terms of BSL/GPLv3.
|
||||
* Commercial or production use requires a valid paid license.
|
||||
* See LICENSE file in repository root for details.
|
||||
*/
|
||||
|
||||
(() => {
|
||||
const order = ["assets", "language", "libraries", "access", "files"];
|
||||
const resourceParts = new Set();
|
||||
const locale = String(document.documentElement.lang || "en").toLowerCase().startsWith("pl") ? "pl" : "en";
|
||||
const strings = {
|
||||
en: {
|
||||
assets: "Preparing the interface", language: "Setting up language",
|
||||
libraries: "Starting the editor", access: "Checking access", files: "Opening the note",
|
||||
complete: "Ready", error: "The note could not be opened", retry: "Reload page",
|
||||
errorDetails: "Check your connection and try again.", progress: "{done} of {total} stages completed",
|
||||
timeout: "Still waiting for the note. Check the connection or reload."
|
||||
},
|
||||
pl: {
|
||||
assets: "Przygotowanie interfejsu", language: "Ustawianie j\u0119zyka",
|
||||
libraries: "Uruchamianie edytora", access: "Sprawdzanie dost\u0119pu", files: "Otwieranie notatki",
|
||||
complete: "Gotowe", error: "Nie uda\u0142o si\u0119 otworzy\u0107 notatki", retry: "Za\u0142aduj ponownie",
|
||||
errorDetails: "Sprawd\u017a po\u0142\u0105czenie i spr\u00f3buj ponownie.", progress: "Uko\u0144czono {done} z {total} etap\u00f3w",
|
||||
timeout: "Nadal oczekujemy na notatk\u0119. Sprawd\u017a po\u0142\u0105czenie lub od\u015bwie\u017c stron\u0119."
|
||||
}
|
||||
}[locale];
|
||||
const completed = new Set();
|
||||
const loadedStyleElements = new WeakSet();
|
||||
let loadedStyleCount = 0;
|
||||
let readyRequested = false;
|
||||
let dismissed = false;
|
||||
let failure = "";
|
||||
const element = id => document.getElementById(id);
|
||||
|
||||
function update() {
|
||||
const overlay = element("app-boot-overlay");
|
||||
if (!overlay || dismissed) return;
|
||||
const count = completed.size;
|
||||
const progress = Math.round((count / order.length) * 100);
|
||||
const next = order.find(stage => !completed.has(stage));
|
||||
const heading = element("app-boot-heading");
|
||||
if (heading) heading.textContent = locale === "pl" ? "Ładowanie…" : "Loading…";
|
||||
const stageText = element("app-boot-stage");
|
||||
const stageCount = element("app-boot-count");
|
||||
const bar = element("app-boot-progress");
|
||||
const fill = element("app-boot-progress-fill");
|
||||
const retry = element("app-boot-retry");
|
||||
if (stageText) stageText.textContent = failure ? strings.error : (next ? strings[next] : strings.complete);
|
||||
if (stageCount) stageCount.textContent = failure || strings.progress.replace("{done}", count).replace("{total}", order.length);
|
||||
if (bar) bar.setAttribute("aria-valuenow", String(progress));
|
||||
if (fill) fill.style.width = `${progress}%`;
|
||||
if (retry) { retry.hidden = !failure; retry.textContent = strings.retry; }
|
||||
overlay.classList.toggle("has-error", Boolean(failure));
|
||||
for (const stage of order) {
|
||||
const node = element(`app-boot-step-${stage}`);
|
||||
if (!node) continue;
|
||||
const isDone = completed.has(stage);
|
||||
node.dataset.status = isDone ? "done" : (stage === next && !failure ? "active" : "waiting");
|
||||
node.querySelector("span")?.replaceChildren(document.createTextNode(strings[stage]));
|
||||
}
|
||||
if (readyRequested && count === order.length && !failure) dismiss();
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
if (dismissed) return;
|
||||
dismissed = true;
|
||||
const overlay = element("app-boot-overlay");
|
||||
if (!overlay) return;
|
||||
overlay.classList.add("is-ready");
|
||||
const remove = () => overlay.remove();
|
||||
overlay.addEventListener("transitionend", remove, { once: true });
|
||||
setTimeout(remove, 300);
|
||||
}
|
||||
|
||||
function complete(stage) {
|
||||
if (dismissed || failure) return;
|
||||
if (stage === "css" || stage === "js") {
|
||||
resourceParts.add(stage);
|
||||
if (resourceParts.has("css") && resourceParts.has("js")) completed.add("assets");
|
||||
} else if (order.includes(stage)) {
|
||||
completed.add(stage);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
function fail(reason) {
|
||||
if (dismissed || failure) return;
|
||||
const safeMessage = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "";
|
||||
failure = safeMessage && safeMessage.length < 180 ? `${strings.error}: ${safeMessage}` : strings.errorDetails;
|
||||
update();
|
||||
}
|
||||
|
||||
document.addEventListener("load", event => {
|
||||
if (!(event.target instanceof HTMLLinkElement) || !event.target.matches("link[data-rustpad-shell-css]")) return;
|
||||
if (loadedStyleElements.has(event.target)) return;
|
||||
loadedStyleElements.add(event.target);
|
||||
loadedStyleCount += 1;
|
||||
const expected = document.querySelectorAll("link[data-rustpad-shell-css]").length;
|
||||
if (expected > 0 && loadedStyleCount >= expected) complete("css");
|
||||
}, true);
|
||||
document.addEventListener("error", event => {
|
||||
if (event.target instanceof HTMLLinkElement && event.target.matches("link[data-rustpad-shell-css]")) {
|
||||
fail(strings.errorDetails);
|
||||
}
|
||||
}, true);
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
element("app-boot-retry")?.addEventListener("click", () => location.reload());
|
||||
update();
|
||||
}, { once: true });
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
if (!dismissed) fail(strings.timeout);
|
||||
}, 45000);
|
||||
|
||||
window.__RUSTPAD_LOADING__ = Object.freeze({
|
||||
complete,
|
||||
skip: complete,
|
||||
ready() { readyRequested = true; update(); if (dismissed) clearTimeout(timeout); },
|
||||
fail,
|
||||
stageDone(stage) {
|
||||
return stage === "css" || stage === "js" ? resourceParts.has(stage) : completed.has(stage);
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in new issue
Block a user