var SERVER = new Object() var BULK_EDIT:Boolean = false var COLUMN_TO_SORT:number var SEARCH_MAPPING = new Object() var UNDO = new Object() var SERVER_CONNECTION = false var WS_AVAILABLE = false var ACTIVE_MENU_ID:string = "" var LAST_BULK_CHECKBOX:HTMLInputElement = 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:string switch(type) { case true: cssClass = "block"; break; case false: cssClass = "none"; break; } var element = document.getElementById(elmID) if (element == null) { return } element.className = cssClass; } function setConnectionState(state:string, text:string = "") { var label:string = 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; document.getElementById(buttonID).setAttribute(attribute, value) } function getLocalData(dataType, id):object { 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():string[] { var channels:string[] = 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] as HTMLElement).style.display != "none") { if ((trs[i].firstChild.firstChild as HTMLInputElement).checked == true) { channels.push(trs[i].id) } } } return channels } function selectChannelRange(checkbox:HTMLInputElement, event:MouseEvent) { 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:HTMLInputElement[] = new Array() for (var i = 1; i < trs.length; i++) { if ((trs[i] as HTMLElement).style.display != "none") { var bulkCheckbox = (trs[i] as HTMLTableRowElement).querySelector("input.bulk") as HTMLInputElement 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:Boolean = false var trs = document.getElementById("content_table").getElementsByTagName("TR") if ((trs[0].firstChild.firstChild as HTMLInputElement).checked == true) { bulk = true } for (var i = 1; i < trs.length; i++) { if ((trs[i] as HTMLElement).style.display != "none") { switch (bulk) { case true: (trs[i].firstChild.firstChild as HTMLInputElement).checked = true break case false: (trs[i].firstChild.firstChild as HTMLInputElement).checked = false break } } } LAST_BULK_CHECKBOX = null return } function bulkEdit() { BULK_EDIT = !BULK_EDIT var className:string 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] as HTMLInputElement).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"); var sortObj = new Object(); var x, xValue; var tableHeader var sortByString = false if (column > 0 && COLUMN_TO_SORT > 0) { tableItems[COLUMN_TO_SORT].className = "pointer"; tableItems[column].className = "sortThis"; } COLUMN_TO_SORT = column; var rows = (table as HTMLTableElement).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:string[] = ["x-active", "x-channelID", "x-name", "_file.m3u.name", "x-group-title", "x-xmltv-file"] channels.forEach(id => { channelKeys.forEach(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") as HTMLInputElement).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] switch (element.toLowerCase().includes(searchValue.toLowerCase())) { case true: document.getElementById(id).style.display = "" break; case false: document.getElementById(id).style.display = "none" break; } } 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:number = parseFloat(element.value) var channelNumbers:number[] = [] var data = SERVER["xepg"]["epgMapping"] var channels = getObjKeys(data) if (isNaN(newNumber)) { alert("{{.alert.invalidChannelNumber}}") return } channels.forEach(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:Server = new Server(cmd) server.request(data) return } function toggleChannelStatus(id:string) { var element:any var status:boolean if(document.getElementById("active")) { var checkbox = (document.getElementById("active") as HTMLInputElement) status = (checkbox).checked } var ids:string[] = getAllSelectedChannels() if (ids.length == 0) { ids.push(id) } ids.forEach(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 as HTMLInputElement).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]') as HTMLInputElement).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: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 as HTMLInputElement).files[0].name var reader = new FileReader(); var file = (document.querySelector('input[type=file]') as HTMLInputElement).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:Server = new Server(cmd) server.request(data) var updateLogo = (document.getElementById('update-icon') as HTMLInputElement) updateLogo.checked = false updateLogo.className = "changed" }; } else { alert("File could not be loaded") } upload.remove() return } } function checkUndo(key:string) { 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 0) elem.options[0] = null; var newSelectedIndex = 0; for (var i=0;i