Files
xTeVe/html/js/base_ts.js
Nathan Coad 57b6be74e2
All checks were successful
continuous-integration/drone/push Build is passing
improve ui checkbox functionality
2026-02-11 13:03:12 +11:00

606 lines
21 KiB
JavaScript

var SERVER = new Object();
var BULK_EDIT = false;
var COLUMN_TO_SORT;
var SEARCH_MAPPING = new Object();
var UNDO = new Object();
var SERVER_CONNECTION = false;
var WS_AVAILABLE = false;
var ACTIVE_MENU_ID = "";
var LAST_FOCUSED_ELEMENT = null;
var LAST_BULK_CHECKBOX = null;
// Menü
var menuItems = new Array();
menuItems.push(new MainMenuItem("playlist", "{{.mainMenu.item.playlist}}", "m3u.png", "{{.mainMenu.headline.playlist}}"));
//menuItems.push(new MainMenuItem("pmsID", "{{.mainMenu.item.pmsID}}", "number.png", "{{.mainMenu.headline.pmsID}}"))
menuItems.push(new MainMenuItem("filter", "{{.mainMenu.item.filter}}", "filter.png", "{{.mainMenu.headline.filter}}"));
menuItems.push(new MainMenuItem("xmltv", "{{.mainMenu.item.xmltv}}", "xmltv.png", "{{.mainMenu.headline.xmltv}}"));
menuItems.push(new MainMenuItem("mapping", "{{.mainMenu.item.mapping}}", "mapping.png", "{{.mainMenu.headline.mapping}}"));
menuItems.push(new MainMenuItem("users", "{{.mainMenu.item.users}}", "users.png", "{{.mainMenu.headline.users}}"));
menuItems.push(new MainMenuItem("settings", "{{.mainMenu.item.settings}}", "settings.png", "{{.mainMenu.headline.settings}}"));
menuItems.push(new MainMenuItem("log", "{{.mainMenu.item.log}}", "log.png", "{{.mainMenu.headline.log}}"));
menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}"));
// Kategorien für die Einstellungen
var settingsCategory = new Array();
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api,use_plexAPI,plex.url,plex.token"));
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"));
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"));
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"));
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"));
function showPopUpElement(elm) {
var allElements = new Array("popup-custom");
for (var i = 0; i < allElements.length; i++) {
showElement(allElements[i], false);
}
showElement(elm, true);
setTimeout(function () {
showElement("popup", true);
}, 10);
return;
}
function showElement(elmID, type) {
var cssClass;
switch (type) {
case true:
cssClass = "block";
break;
case false:
cssClass = "none";
break;
}
var element = document.getElementById(elmID);
if (element == null) {
return;
}
element.className = cssClass;
element.setAttribute("aria-hidden", type == true ? "false" : "true");
if (elmID == "loading" && document.body != null) {
document.body.setAttribute("aria-busy", type == true ? "true" : "false");
}
if (elmID == "popup") {
var popupContent_1 = document.getElementById("popup-custom");
if (type == true) {
LAST_FOCUSED_ELEMENT = document.activeElement;
if (popupContent_1 != null) {
setTimeout(function () {
popupContent_1.focus();
}, 20);
}
}
else {
if (LAST_FOCUSED_ELEMENT != null && LAST_FOCUSED_ELEMENT.focus != undefined) {
setTimeout(function () {
LAST_FOCUSED_ELEMENT.focus();
}, 20);
}
LAST_FOCUSED_ELEMENT = null;
}
}
}
function announceToScreenReader(message) {
if (message == undefined || message.length == 0) {
return;
}
var region = document.getElementById("sr-announcer");
if (region == null) {
return;
}
region.innerText = "";
setTimeout(function () {
region.innerText = message;
}, 20);
}
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;
indicator.setAttribute("aria-label", "Connection status: " + label);
announceToScreenReader("Connection status " + label);
}
function changeButtonAction(element, buttonID, attribute) {
var value = element.options[element.selectedIndex].value;
document.getElementById(buttonID).setAttribute(attribute, value);
}
function getLocalData(dataType, id) {
var data = new Object();
switch (dataType) {
case "m3u":
data = SERVER["settings"]["files"][dataType][id];
break;
case "hdhr":
data = SERVER["settings"]["files"][dataType][id];
break;
case "filter":
case "custom-filter":
case "group-title":
if (id == -1) {
data["active"] = true;
data["caseSensitive"] = false;
data["description"] = "";
data["exclude"] = "";
data["filter"] = "";
data["include"] = "";
data["name"] = "";
data["type"] = "group-title";
SERVER["settings"]["filter"][id] = data;
}
data = SERVER["settings"]["filter"][id];
break;
case "xmltv":
data = SERVER["settings"]["files"][dataType][id];
break;
case "users":
data = SERVER["users"][id]["data"];
break;
case "mapping":
data = SERVER["xepg"]["epgMapping"][id];
break;
case "m3uGroups":
data = SERVER["data"]["playlist"]["m3u"]["groups"];
break;
}
return data;
}
function getObjKeys(obj) {
var keys = new Array();
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
keys.push(i);
}
}
return keys;
}
function getAllSelectedChannels() {
var channels = new Array();
if (BULK_EDIT == false) {
return channels;
}
var trs = document.getElementById("content_table").getElementsByTagName("TR");
for (var i = 1; i < trs.length; i++) {
if (trs[i].style.display != "none") {
if (trs[i].firstChild.firstChild.checked == true) {
channels.push(trs[i].id);
}
}
}
return channels;
}
function selectChannelRange(checkbox, event) {
if (BULK_EDIT == false || checkbox == undefined || checkbox == null) {
return;
}
var table = document.getElementById("content_table");
if (table == null) {
return;
}
var trs = table.getElementsByTagName("TR");
var visibleCheckboxes = new Array();
for (var i = 1; i < trs.length; i++) {
if (trs[i].style.display != "none") {
var bulkCheckbox = trs[i].querySelector("input.bulk");
if (bulkCheckbox != null) {
visibleCheckboxes.push(bulkCheckbox);
}
}
}
var currentIndex = visibleCheckboxes.indexOf(checkbox);
var previousIndex = -1;
if (LAST_BULK_CHECKBOX != null) {
previousIndex = visibleCheckboxes.indexOf(LAST_BULK_CHECKBOX);
}
if (event != undefined && event.shiftKey == true && previousIndex > -1 && currentIndex > -1) {
var start = Math.min(previousIndex, currentIndex);
var end = Math.max(previousIndex, currentIndex);
for (var i = start; i <= end; i++) {
visibleCheckboxes[i].checked = checkbox.checked;
}
}
LAST_BULK_CHECKBOX = checkbox;
}
function selectAllChannels() {
var bulk = false;
var trs = document.getElementById("content_table").getElementsByTagName("TR");
if (trs[0].firstChild.firstChild.checked == true) {
bulk = true;
}
for (var i = 1; i < trs.length; i++) {
if (trs[i].style.display != "none") {
switch (bulk) {
case true:
trs[i].firstChild.firstChild.checked = true;
break;
case false:
trs[i].firstChild.firstChild.checked = false;
break;
}
}
}
LAST_BULK_CHECKBOX = null;
return;
}
function bulkEdit() {
BULK_EDIT = !BULK_EDIT;
var className;
var rows = document.getElementsByClassName("bulk");
switch (BULK_EDIT) {
case true:
className = "bulk showBulk";
break;
case false:
className = "bulk hideBulk";
break;
}
for (var i = 0; i < rows.length; i++) {
rows[i].className = className;
rows[i].checked = false;
}
LAST_BULK_CHECKBOX = null;
return;
}
function sortTable(column) {
//console.log(columm);
if (column == COLUMN_TO_SORT) {
return;
}
var table = document.getElementById("content_table");
var tableHead = table.getElementsByTagName("TR")[0];
var tableItems = tableHead.getElementsByTagName("TD");
for (var h = 0; h < tableItems.length; h++) {
if (tableItems[h].getAttribute("role") == "columnheader") {
tableItems[h].setAttribute("aria-sort", "none");
}
}
var sortObj = new Object();
var x, xValue;
var tableHeader;
var sortByString = false;
if (column > 0 && COLUMN_TO_SORT > 0) {
tableItems[COLUMN_TO_SORT].classList.remove("sortThis");
tableItems[COLUMN_TO_SORT].classList.add("pointer");
tableItems[column].classList.remove("pointer");
tableItems[column].classList.add("sortThis");
}
COLUMN_TO_SORT = column;
var mobileSort = document.getElementById("mapping-sort-mobile");
if (mobileSort != null && (column == 1 || column == 3 || column == 4 || column == 5)) {
mobileSort.value = column.toString();
}
if (tableItems[column] != undefined && tableItems[column].getAttribute("role") == "columnheader") {
tableItems[column].setAttribute("aria-sort", "ascending");
}
var rows = table.rows;
if (rows[1] != undefined) {
tableHeader = rows[0];
x = rows[1].getElementsByTagName("TD")[column];
for (i = 1; i < rows.length; i++) {
x = rows[i].getElementsByTagName("TD")[column];
switch (x.childNodes[0].tagName.toLowerCase()) {
case "input":
xValue = x.getElementsByTagName("INPUT")[0].value.toLowerCase();
break;
case "p":
xValue = x.getElementsByTagName("P")[0].innerText.toLowerCase();
break;
default: console.log(x.childNodes[0].tagName);
}
if (xValue == "" || xValue == NaN) {
xValue = i;
sortObj[i] = rows[i];
}
else {
switch (isNaN(xValue)) {
case false:
xValue = parseFloat(xValue);
sortObj[xValue] = rows[i];
break;
case true:
sortByString = true;
sortObj[xValue.toLowerCase() + i] = rows[i];
break;
}
}
}
while (table.firstChild) {
table.removeChild(table.firstChild);
}
var sortValues = getObjKeys(sortObj);
if (sortByString == true) {
sortValues.sort();
console.log(sortValues);
}
else {
function sortFloat(a, b) {
return a - b;
}
sortValues.sort(sortFloat);
}
table.appendChild(tableHeader);
for (var i = 0; i < sortValues.length; i++) {
table.appendChild(sortObj[sortValues[i]]);
}
}
return;
}
function createSearchObj() {
SEARCH_MAPPING = new Object();
var data = SERVER["xepg"]["epgMapping"];
var channels = getObjKeys(data);
var channelKeys = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"];
channels.forEach(function (id) {
SEARCH_MAPPING[id] = "";
channelKeys.forEach(function (key) {
if (key == "x-active") {
switch (data[id][key]) {
case true:
SEARCH_MAPPING[id] = "online ";
break;
case false:
SEARCH_MAPPING[id] = "offline ";
break;
}
}
else {
if (key == "x-xmltv-file") {
var xmltvFile = getValueFromProviderFile(data[id][key], "xmltv", "name");
if (xmltvFile != undefined) {
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + xmltvFile + " ";
}
}
else {
SEARCH_MAPPING[id] = SEARCH_MAPPING[id] + data[id][key] + " ";
}
}
});
});
return;
}
function searchInMapping() {
var searchValue = document.getElementById("searchMapping").value;
var trs = document.getElementById("content_table").getElementsByTagName("TR");
for (var i = 1; i < trs.length; ++i) {
var id = trs[i].getAttribute("id");
var element = SEARCH_MAPPING[id];
if (element == undefined) {
continue;
}
switch (element.toLowerCase().includes(searchValue.toLowerCase())) {
case true:
document.getElementById(id).style.display = "";
break;
case false:
document.getElementById(id).style.display = "none";
break;
}
}
announceToScreenReader("Search updated");
return;
}
function calculateWrapperHeight() {
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 = freeSpace + "px";
}
return;
}
function changeChannelNumber(element) {
var dbID = element.parentNode.parentNode.id;
var newNumber = parseFloat(element.value);
var channelNumbers = [];
var data = SERVER["xepg"]["epgMapping"];
var channels = getObjKeys(data);
if (isNaN(newNumber)) {
alert("{{.alert.invalidChannelNumber}}");
return;
}
channels.forEach(function (id) {
var channelNumber = parseFloat(data[id]["x-channelID"]);
channelNumbers.push(channelNumber);
});
for (var i = 0; i < channelNumbers.length; i++) {
if (channelNumbers.indexOf(newNumber) == -1) {
break;
}
if (Math.floor(newNumber) == newNumber) {
newNumber = newNumber + 1;
}
else {
newNumber = newNumber + 0.1;
newNumber.toFixed(1);
newNumber = Math.round(newNumber * 10) / 10;
}
}
data[dbID]["x-channelID"] = newNumber.toString();
element.value = newNumber;
console.log(data[dbID]["x-channelID"]);
if (COLUMN_TO_SORT == 1) {
COLUMN_TO_SORT = -1;
sortTable(1);
}
return;
}
function backup() {
var data = new Object();
console.log("Backup data");
var cmd = "xteveBackup";
console.log("SEND TO SERVER");
console.log(data);
var server = new Server(cmd);
server.request(data);
return;
}
function toggleChannelStatus(id) {
var element;
var status;
if (document.getElementById("active")) {
var checkbox = document.getElementById("active");
status = (checkbox).checked;
}
var ids = getAllSelectedChannels();
if (ids.length == 0) {
ids.push(id);
}
ids.forEach(function (id) {
var channel = SERVER["xepg"]["epgMapping"][id];
channel["x-active"] = status;
switch (channel["x-active"]) {
case true:
if (channel["x-xmltv-file"] == "-" || channel["x-mapping"] == "-") {
if (BULK_EDIT == false) {
alert(channel["x-name"] + ": Missing XMLTV file / channel");
checkbox.checked = false;
}
channel["x-active"] = false;
}
break;
case false:
// code...
break;
}
if (channel["x-active"] == false) {
document.getElementById(id).className = "notActiveEPG";
}
else {
document.getElementById(id).className = "activeEPG";
}
});
}
function restore() {
if (document.getElementById('upload')) {
document.getElementById('upload').remove();
}
var restore = document.createElement("INPUT");
restore.setAttribute("type", "file");
restore.setAttribute("class", "notVisible");
restore.setAttribute("name", "");
restore.id = "upload";
document.body.appendChild(restore);
restore.click();
restore.onchange = function () {
var filename = restore.files[0].name;
var check = confirm("File: " + filename + "\n{{.confirm.restore}}");
if (check == true) {
var reader = new FileReader();
var file = document.querySelector('input[type=file]').files[0];
if (file) {
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
var data = new Object();
var cmd = "xteveRestore";
data["base64"] = reader.result;
var server = new Server(cmd);
server.request(data);
};
}
else {
alert("File could not be loaded");
}
restore.remove();
return;
}
};
return;
}
function uploadLogo() {
if (document.getElementById('upload')) {
document.getElementById('upload').remove();
}
var upload = document.createElement("INPUT");
upload.setAttribute("type", "file");
upload.setAttribute("class", "notVisible");
upload.setAttribute("name", "");
upload.id = "upload";
document.body.appendChild(upload);
upload.click();
upload.onblur = function () {
alert();
};
upload.onchange = function () {
var filename = upload.files[0].name;
var reader = new FileReader();
var file = document.querySelector('input[type=file]').files[0];
if (file) {
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
var data = new Object();
var cmd = "uploadLogo";
data["base64"] = reader.result;
data["filename"] = file.name;
var server = new Server(cmd);
server.request(data);
var updateLogo = document.getElementById('update-icon');
updateLogo.checked = false;
updateLogo.className = "changed";
};
}
else {
alert("File could not be loaded");
}
upload.remove();
return;
};
}
function checkUndo(key) {
switch (key) {
case "epgMapping":
if (UNDO.hasOwnProperty(key)) {
SERVER["xepg"][key] = JSON.parse(JSON.stringify(UNDO[key]));
}
else {
UNDO[key] = JSON.parse(JSON.stringify(SERVER["xepg"][key]));
}
break;
default:
break;
}
return;
}
function sortSelect(elem) {
var tmpAry = [];
var selectedValue = elem[elem.selectedIndex].value;
for (var i = 0; i < elem.options.length; i++)
tmpAry.push(elem.options[i]);
tmpAry.sort(function (a, b) { return (a.text < b.text) ? -1 : 1; });
while (elem.options.length > 0)
elem.options[0] = null;
var newSelectedIndex = 0;
for (var i = 0; i < tmpAry.length; i++) {
elem.options[i] = tmpAry[i];
if (elem.options[i].value == selectedValue)
newSelectedIndex = i;
}
elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
return;
}
function updateLog() {
console.log("TOKEN");
var server = new Server("updateLog");
server.request(new Object());
}