Redesign UI and add first-party Docker runtime support

This commit is contained in:
2026-02-11 11:04:39 +11:00
parent 0e999b85b9
commit 8cb9e43a72
22 changed files with 1730 additions and 811 deletions

View File

@@ -12,6 +12,9 @@ function login() {
inputs[i].style.borderColor = "red";
err = true;
}
else {
inputs[i].style.borderColor = "";
}
data[key] = value;
}
if (err == true) {
@@ -20,7 +23,6 @@ function login() {
}
if (data.hasOwnProperty("confirm")) {
if (data["confirm"] != data["password"]) {
alert("sdafsd");
document.getElementById('password').style.borderColor = "red";
document.getElementById('confirm').style.borderColor = "red";
document.getElementById("err").innerHTML = "{{.account.failed}}";

View File

@@ -5,6 +5,7 @@ var SEARCH_MAPPING = new Object();
var UNDO = new Object();
var SERVER_CONNECTION = false;
var WS_AVAILABLE = false;
var ACTIVE_MENU_ID = "";
// Menü
var menuItems = new Array();
menuItems.push(new MainMenuItem("playlist", "{{.mainMenu.item.playlist}}", "m3u.png", "{{.mainMenu.headline.playlist}}"));
@@ -44,7 +45,36 @@ function showElement(elmID, type) {
cssClass = "none";
break;
}
document.getElementById(elmID).className = cssClass;
var element = document.getElementById(elmID);
if (element == null) {
return;
}
element.className = cssClass;
}
function setConnectionState(state, text) {
var label = text;
if (label == undefined || label.length == 0) {
switch (state) {
case "online":
label = "Connected";
break;
case "busy":
label = "Syncing";
break;
case "offline":
label = "Offline";
break;
default:
label = "Connecting";
break;
}
}
var indicator = document.getElementById("connection-indicator");
if (indicator == null) {
return;
}
indicator.className = "status-" + state;
indicator.innerText = label;
}
function changeButtonAction(element, buttonID, attribute) {
var value = element.options[element.selectedIndex].value;
@@ -272,14 +302,15 @@ function searchInMapping() {
return;
}
function calculateWrapperHeight() {
if (document.getElementById("box-wrapper")) {
var elm = document.getElementById("box-wrapper");
var divs = new Array("myStreamsBox", "clientInfo", "content");
var elementsHeight = 0 - elm.offsetHeight;
for (var i = 0; i < divs.length; i++) {
elementsHeight = elementsHeight + document.getElementById(divs[i]).offsetHeight;
var elm = document.getElementById("box-wrapper");
var content = document.getElementById("content");
if (elm != null && content != null) {
var contentTop = content.getBoundingClientRect().top;
var freeSpace = window.innerHeight - contentTop - 26;
if (freeSpace < 180) {
freeSpace = 180;
}
elm.style.height = window.innerHeight - elementsHeight + "px";
elm.style.height = freeSpace + "px";
}
return;
}

View File

@@ -43,6 +43,7 @@ var MainMenuItem = /** @class */ (function (_super) {
var item = document.createElement("LI");
item.setAttribute("onclick", "javascript: openThisMenu(this)");
item.setAttribute("id", this.id);
item.setAttribute("data-menu", this.menuKey);
var img = this.createIMG(this.imgSrc);
var value = this.createValue(this.value);
item.appendChild(img);
@@ -560,7 +561,7 @@ var ShowContent = /** @class */ (function (_super) {
input.setAttribute("id", "searchMapping");
input.setAttribute("placeholder", "{{.button.search}}");
input.className = "search";
input.setAttribute("onchange", 'javascript: searchInMapping()');
input.setAttribute("oninput", 'javascript: searchInMapping()');
interaction.appendChild(input);
break;
case "settings":
@@ -668,10 +669,127 @@ var ShowContent = /** @class */ (function (_super) {
};
return ShowContent;
}(Content));
var SHELL_LAYOUT_READY = false;
function setLayoutMenuState(open) {
if (document.body == null) {
return;
}
if (open == true) {
document.body.classList.add("menu-open");
}
else {
document.body.classList.remove("menu-open");
}
}
function toggleLayoutMenu() {
if (document.body == null) {
return;
}
var isOpen = document.body.classList.contains("menu-open");
setLayoutMenuState(!isOpen);
}
function closeLayoutMenuIfMobile() {
if (window.innerWidth <= 900) {
setLayoutMenuState(false);
}
}
function setActiveMenu(menuID) {
ACTIVE_MENU_ID = menuID.toString();
var menu = document.getElementById("main-menu");
if (menu == null) {
return;
}
var items = menu.getElementsByTagName("LI");
for (var i = 0; i < items.length; i++) {
items[i].classList.remove("menu-active");
}
var activeItem = document.getElementById(ACTIVE_MENU_ID);
if (activeItem != null) {
activeItem.classList.add("menu-active");
}
}
function renderStatusCards() {
var wrapper = document.getElementById("status-cards");
if (wrapper == null || SERVER.hasOwnProperty("clientInfo") == false) {
return;
}
var info = SERVER["clientInfo"];
var errors = parseInt(info["errors"], 10);
var warnings = parseInt(info["warnings"], 10);
var cards = [
{ label: "Streams", value: info["streams"], tone: "ok" },
{ label: "EPG Source", value: info["epgSource"], tone: "neutral" },
{ label: "XEPG Channels", value: info["xepg"], tone: "ok" },
{ label: "Errors", value: info["errors"], tone: errors > 0 ? "error" : "ok" },
{ label: "Warnings", value: info["warnings"], tone: warnings > 0 ? "warn" : "ok" },
{ label: "DVR", value: info["DVR"], tone: "neutral" }
];
wrapper.innerHTML = "";
cards.forEach(function (card) {
var box = document.createElement("DIV");
box.className = "status-card status-card-" + card.tone;
var label = document.createElement("P");
label.className = "status-card-label";
label.innerText = card.label;
var value = document.createElement("P");
value.className = "status-card-value";
if (card.value == undefined || card.value == "") {
value.innerText = "-";
}
else {
value.innerText = card.value;
}
box.appendChild(label);
box.appendChild(value);
wrapper.appendChild(box);
});
}
function initShellLayout() {
if (SHELL_LAYOUT_READY == true) {
return;
}
var toggle = document.getElementById("menu-toggle");
if (toggle != null) {
toggle.onclick = function () {
toggleLayoutMenu();
};
}
var overlay = document.getElementById("layout-overlay");
if (overlay != null) {
overlay.onclick = function () {
setLayoutMenuState(false);
};
}
document.addEventListener("keydown", function (event) {
if (event.key == "Escape") {
setLayoutMenuState(false);
showElement("popup", false);
return;
}
if (event.key == "/") {
var target = event.target;
var onInput = target.tagName == "INPUT" || target.tagName == "TEXTAREA" || target.tagName == "SELECT";
if (onInput == true) {
return;
}
var search = document.getElementById("searchMapping");
if (search != null) {
event.preventDefault();
search.focus();
}
}
});
setConnectionState("idle");
SHELL_LAYOUT_READY = true;
}
function PageReady() {
initShellLayout();
var server = new Server("getServerConfig");
server.request(new Object());
window.addEventListener("resize", function () {
if (window.innerWidth > 900) {
setLayoutMenuState(false);
}
calculateWrapperHeight();
}, true);
setInterval(function () {
@@ -688,6 +806,7 @@ function createLayout() {
document.getElementById(keys[i]).innerHTML = obj[keys[i]];
}
}
renderStatusCards();
if (!document.getElementById("main-menu")) {
return;
}
@@ -713,12 +832,27 @@ function createLayout() {
break;
}
}
if (ACTIVE_MENU_ID.length > 0 && document.getElementById(ACTIVE_MENU_ID)) {
setActiveMenu(ACTIVE_MENU_ID);
}
var content = document.getElementById("content");
var menu = document.getElementById("main-menu");
if (ACTIVE_MENU_ID.length == 0 && content != null && menu != null) {
if (content.innerHTML.replace(/\\s/g, "").length == 0) {
var firstItem = menu.getElementsByTagName("LI")[0];
if (firstItem != undefined) {
firstItem.click();
}
}
}
return;
}
function openThisMenu(element) {
var id = element.id;
var content = new ShowContent(id);
setActiveMenu(id);
content.show();
closeLayoutMenuIfMobile();
calculateWrapperHeight();
return;
}

View File

@@ -11,6 +11,7 @@ var Server = /** @class */ (function () {
if (this.cmd != "updateLog") {
showElement("loading", true);
UNDO = new Object();
setConnectionState("busy");
}
switch (window.location.protocol) {
case "http:":
@@ -25,6 +26,9 @@ var Server = /** @class */ (function () {
var ws = new WebSocket(url);
ws.onopen = function () {
WS_AVAILABLE = true;
if (data["cmd"] != "updateLog") {
setConnectionState("busy");
}
console.log("REQUEST (JS):");
console.log(data);
console.log("REQUEST: (JSON)");
@@ -34,6 +38,7 @@ var Server = /** @class */ (function () {
ws.onerror = function (e) {
console.log("No websocket connection to xTeVe could be established. Check your network configuration.");
SERVER_CONNECTION = false;
setConnectionState("offline");
if (WS_AVAILABLE == false) {
alert("No websocket connection to xTeVe could be established. Check your network configuration.");
}
@@ -41,6 +46,9 @@ var Server = /** @class */ (function () {
ws.onmessage = function (e) {
SERVER_CONNECTION = false;
showElement("loading", false);
if (data["cmd"] != "updateLog") {
setConnectionState("online");
}
console.log("RESPONSE:");
var response = JSON.parse(e.data);
console.log(response);
@@ -48,6 +56,7 @@ var Server = /** @class */ (function () {
document.cookie = "Token=" + response["token"];
}
if (response["status"] == false) {
setConnectionState("offline");
alert(response["err"]);
if (response.hasOwnProperty("reload")) {
location.reload();