169 lines
5.6 KiB
JavaScript
169 lines
5.6 KiB
JavaScript
// /public/assets/js/fakecheck/fakecheck.core.js
|
||
|
||
(function() {
|
||
|
||
// Namespace
|
||
window.usbcheck = window.usbcheck || {};
|
||
const usbcheck = window.usbcheck;
|
||
|
||
const cfg = window.usbConfig || {};
|
||
|
||
// URL-Detection
|
||
function detectApiBaseUrl() {
|
||
const host = window.location.hostname || "";
|
||
if (host === "staging.usbcheck.it" || host.endsWith(".staging.usbcheck.it")) {
|
||
return "https://api.staging.usbcheck.it";
|
||
}
|
||
return "https://api.usbcheck.it";
|
||
}
|
||
|
||
// Locale aus Config:
|
||
// - bevorzugt fakecheck.locale (aus PHP fakecheck-Block)
|
||
// - sonst cfg.lang
|
||
const locale =
|
||
(cfg.fakecheck && cfg.fakecheck.locale)
|
||
|| cfg.lang
|
||
|| "en";
|
||
|
||
// Config bereitstellen
|
||
usbcheck.cfg = {
|
||
// wenn fakecheck.baseUrl vorhanden ist → bevorzugen
|
||
baseUrl: (cfg.fakecheck && cfg.fakecheck.baseUrl) || cfg.baseUrl || "",
|
||
locale: (locale || "en").toLowerCase(),
|
||
apiBase: (cfg.fakecheck && cfg.fakecheck.apiBaseUrl) || cfg.apiBaseUrl || detectApiBaseUrl(),
|
||
loggedIn: !!cfg.isLoggedIn
|
||
};
|
||
|
||
// -----------------------------------
|
||
// i18n – JSON laden + Helfer
|
||
// -----------------------------------
|
||
|
||
usbcheck.locale = usbcheck.cfg.locale || "en";
|
||
usbcheck.i18n = {};
|
||
|
||
function loadI18n() {
|
||
// Pfad wie bei deinen JSONs: /public/assets/i18n/de.json etc.
|
||
const assetsBase = cfg.assetsBase || "/assets";
|
||
const url = assetsBase.replace(/\/+$/, "") + "/i18n/" + usbcheck.locale + ".json";
|
||
|
||
fetch(url)
|
||
.then(res => {
|
||
if (!res.ok) throw new Error("HTTP " + res.status);
|
||
return res.json();
|
||
})
|
||
.then(data => {
|
||
usbcheck.i18n = data || {};
|
||
// console.debug("usbcheck i18n loaded:", usbcheck.locale, usbcheck.i18n);
|
||
})
|
||
.catch(err => {
|
||
console.warn("usbcheck i18n konnte nicht geladen werden:", err);
|
||
usbcheck.i18n = {};
|
||
});
|
||
}
|
||
|
||
// Key-Lookup: "fake_ui.status_ready"
|
||
usbcheck.t = function t(key, fallback) {
|
||
if (!key) return (fallback != null ? fallback : "");
|
||
const parts = String(key).split(".");
|
||
let cur = usbcheck.i18n;
|
||
for (let i = 0; i < parts.length; i++) {
|
||
const p = parts[i];
|
||
if (!cur || typeof cur !== "object" || !(p in cur)) {
|
||
return (fallback != null ? fallback : key);
|
||
}
|
||
cur = cur[p];
|
||
}
|
||
if (cur == null) return (fallback != null ? fallback : key);
|
||
return cur;
|
||
};
|
||
|
||
// Format-Variante mit Platzhaltern {name}, {mode}, {size}, ...
|
||
usbcheck.tFmt = function tFmt(key, fallback, vars) {
|
||
let str = usbcheck.t(key, fallback);
|
||
if (!vars) return str;
|
||
for (const k in vars) {
|
||
if (!Object.prototype.hasOwnProperty.call(vars, k)) continue;
|
||
const re = new RegExp("\\{" + k.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") + "\\}", "g");
|
||
str = str.replace(re, vars[k]);
|
||
}
|
||
return str;
|
||
};
|
||
|
||
// direkt beim Laden JSON holen
|
||
loadI18n();
|
||
|
||
|
||
// ---------- Hilfsfunktionen ----------
|
||
usbcheck.log = function logLine(message, level = "info") {
|
||
const logEl = document.querySelector("#fc-log");
|
||
if (!logEl) return;
|
||
const line = document.createElement("div");
|
||
line.className = "fc-log-line";
|
||
const prefix =
|
||
level === "error" ? "[ERROR] " :
|
||
level === "warn" ? "[WARN] " :
|
||
"[INFO] ";
|
||
line.innerHTML = `<strong>${prefix}</strong>${message}`;
|
||
logEl.appendChild(line);
|
||
logEl.scrollTop = logEl.scrollHeight;
|
||
};
|
||
|
||
usbcheck.setStatus = function(msg) {
|
||
const el = document.querySelector("#fc-status-text");
|
||
if (el) el.textContent = msg;
|
||
};
|
||
|
||
usbcheck.setModeLabel = function(msg) {
|
||
const el = document.querySelector("#fc-status-mode");
|
||
if (el) el.textContent = msg;
|
||
};
|
||
|
||
usbcheck.setProgress = function(percent) {
|
||
const el = document.querySelector("#fc-progress-inner");
|
||
if (!el) return;
|
||
const v = Math.min(100, Math.max(0, percent));
|
||
el.style.width = v + "%";
|
||
};
|
||
|
||
usbcheck.setOverallStatus = function(state, text) {
|
||
const pill = document.querySelector("#fc-overall-status-pill");
|
||
const label = document.querySelector("#fc-overall-status-text");
|
||
if (!pill || !label) return;
|
||
|
||
pill.classList.remove("fc-pill-ok","fc-pill-warn","fc-pill-bad");
|
||
|
||
if (state === "ok") pill.classList.add("fc-pill-ok");
|
||
else if (state === "warn") pill.classList.add("fc-pill-warn");
|
||
else pill.classList.add("fc-pill-bad");
|
||
|
||
label.textContent = text;
|
||
};
|
||
|
||
usbcheck.formatBytes = function(bytes) {
|
||
if (bytes == null) return "–";
|
||
const units = ["B", "KB", "MB", "GB", "TB"];
|
||
let u = 0, v = bytes;
|
||
while (v >= 1024 && u < units.length - 1) { v /= 1024; u++; }
|
||
return v.toFixed(1) + " " + units[u];
|
||
};
|
||
|
||
usbcheck.formatMbps = function(bytes, seconds) {
|
||
if (!seconds || seconds <= 0) return "–";
|
||
const mbits = (bytes * 8) / 1e6;
|
||
return mbits.toFixed(1) + " Mbit/s";
|
||
};
|
||
|
||
usbcheck.formatDuration = function(seconds) {
|
||
if (!seconds) return "–";
|
||
const s = Math.round(seconds);
|
||
if (s < 60) return s + " s";
|
||
const m = Math.floor(s / 60);
|
||
const r = s % 60;
|
||
if (m < 60) return `${m} min ${r}s`;
|
||
const h = Math.floor(m / 60);
|
||
const rm = m % 60;
|
||
return `${h} h ${rm} min`;
|
||
};
|
||
|
||
})();
|