simple-liveresults/liveresults.js

315 lines
14 KiB
JavaScript

// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3
var tabsCreated = false;
function createTabs(tabArray, tabNameArray) {
for (let i = 0; i < tabArray.length; i++) {
let StrTab = `<li class="tab" role="presentation"><a class="tab-button" role="tab" data-toggle="tab" onclick="changeTab('${tabArray[i]}')" id="${tabArray[i]}-tab" href="#tab-${tabArray[i]}" aria-controls="${tabArray[i]}" aria-selected="false">${tabNameArray[i].Class.Name}</a></li>`;
let StrCont = '<div class="tab-content" id="' + tabArray[i]+'" role="tabpanel" aria-labelledby="' + tabArray[i] + '-tab"></div>'
document.getElementById("classes-tabs").innerHTML += StrTab;
document.getElementById("classes-tab-content").innerHTML += StrCont;
tabsCreated = true;
}
}
function TimeFormater(stamp) {
//diff /= 60;
let hours = Math.floor(stamp / 3600);
let minutes = Math.floor((stamp - hours * 3600) / 60);
let seconds = stamp - minutes * 60;
let hourString;
if(hours!==0){
hourString = ("0" + hours).slice(-2) + ':';
}
else{
hourString = '';
}
return hourString +("0" + minutes).slice(-2) + ":" + ("0" + seconds).slice(-2);
}
function sortTable(tableToCheck) {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById(tableToCheck);
switching = true;
/* Make a loop that will continue until
no switching has been done: */
while (switching) {
// Start by saying: no switching is done:
switching = false;
rows = table.rows;
/* Loop through all table rows (except the
first, which contains table headers): */
for (i = 1; i < (rows.length - 1); i++) {
// Start by saying there should be no switching:
shouldSwitch = false;
/* Get the two elements you want to compare,
one from current row and one from the next: */
x = rows[i].getElementsByTagName("td")[2];
y = rows[i + 1].getElementsByTagName("td")[2];
// Check if the two rows should switch place:
if (parseInt(x.persTime, 10) > parseInt(y.persTime, 10)) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
/* If a switch has been marked, make the switch
and mark that a switch has been done: */
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}/*
for (i = 1; i < (rows.length); i++) {
rows[i].getElementsByTagName("td")[0].innerHTML = i+".";
}*/
}
function loadresults() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let xmlObj = JSON.parse(this.responseText);
var classesArray = [];
for (let i = 0; i < xmlObj.ClassResult.length; i++) {
classesArray[i] = xmlObj.ClassResult[i].Class.Name.replace(/ |\//g, "_");;
}
//console.log(classesArray);
if (tabsCreated == false) {
createTabs(classesArray, xmlObj.ClassResult);
}
document.getElementById("alle-cont").innerHTML = "";
let rowCount = 0;
document.getElementById("header-brand").innerHTML=xmlObj.Event.Name;
//create tables
for (let i = 0; i < xmlObj.ClassResult.length; i++) {
let resultTable = "";
let splitTimes = `<table class="ResultTable splits-table" id="${classesArray[i]}-splits"><tr class="splits-labels">`;
let winnerTime;
let controlArray = [];
if(typeof(xmlObj.ClassResult[i].PersonResult)!== 'undefined'){
if(typeof(xmlObj.ClassResult[i].PersonResult[0])!== 'undefined' && typeof(xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime)!== 'undefined'){
splitTimes += '<td></td>'
controlArray = Array.from(xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime);
for (let s = 0; s < xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime.length; s++){
splitTimes += `<td ctrlcode="${xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime[s].ControlCode}">${(s+1)}-${xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime[s].ControlCode}</td>`;
}
}
}
splitTimes += '</tr>'
if(typeof(xmlObj.ClassResult[i].PersonResult)!== 'undefined'){
for (let k = 0; k < xmlObj.ClassResult[i].PersonResult.length; k++) {
rowCount += 1;
if(typeof(xmlObj.ClassResult[i].PersonResult[k].Result)!== 'undefined' && typeof(xmlObj.ClassResult[i].PersonResult[k].Result.Position)!== 'undefined'){
resultTable += `<tr><td id="Ranking">${xmlObj.ClassResult[i].PersonResult[k].Result.Position}.</td>`;
}
else{
resultTable += `<tr><td id="Ranking"></td>`;
}
//add name
resultTable += "<td>" + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Given + " " + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Family + "</td>"
//add club
if (xmlObj.ClassResult[i].PersonResult[k].Organisation.Name!='[object Object]'){
resultTable += '<td class="club-collum">' + xmlObj.ClassResult[i].PersonResult[k].Organisation.Name + '</td>'
}
else{
resultTable += '<td class="club-collum">' + "" + '</td>'
}
let timeUsedStamp = xmlObj.ClassResult[i].PersonResult[k].Result.Time;
let timeUsed = TimeFormater(timeUsedStamp);
//Check if person is dsq and add time
let persStatus = xmlObj.ClassResult[i].PersonResult[k].Result.Status;
if (persStatus == 'OK') {
resultTable += '<td persTime="'+timeUsedStamp+'" persStatus="'+xmlObj.ClassResult[i].PersonResult[k].Result.Status+'">' + timeUsed + '</td>'
}
else if (persStatus == 'Disqualified') {
resultTable += '<td persTime="'+timeUsedStamp+'" persStatus="'+xmlObj.ClassResult[i].PersonResult[k].Result.Status+'">' + 'DSQ' +'</td>';
}
else if (persStatus == 'Active'){
resultTable += '<td persTime="'+timeUsedStamp+'" persStatus="'+xmlObj.ClassResult[i].PersonResult[k].Result.Status+'">' + 'Ikke i mål' +'</td>';
}
else if (persStatus == 'DidNotStart'){
resultTable += '<td persTime="'+timeUsedStamp+'" persStatus="'+xmlObj.ClassResult[i].PersonResult[k].Result.Status+'">' + 'Ikke startet' +'</td>';
}
else {
resultTable += '<td persTime="'+timeUsedStamp+'" persStatus="'+xmlObj.ClassResult[i].PersonResult[k].Result.Status+'">' + persStatus +'</td>';
}
//add time difference to winner
if (!xmlObj.ClassResult[i].PersonResult[k].Result.Position){
resultTable += '<td>' + "" + '</td>'
}
else if(xmlObj.ClassResult[i].PersonResult[k].Result.Time==0){
resultTable += '<td>' + "" + '</td>'
}
else if (xmlObj.ClassResult[i].PersonResult[k].Result.Position!=1){
let timeDiff = xmlObj.ClassResult[i].PersonResult[k].Result.Time-winnerTime;
resultTable += '<td>+' + TimeFormater(timeDiff) + '</td>'
}
else if (xmlObj.ClassResult[i].PersonResult[k].Result.Position=1){
winnerTime = xmlObj.ClassResult[i].PersonResult[k].Result.Time;
resultTable += '<td>' + "" + '</td>'
}
resultTable += "</tr>";
if (typeof(xmlObj.ClassResult[i].PersonResult[k])!== 'undefined' && typeof(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime)!== 'undefined' && persStatus == 'OK'){
splitTimes += '<tr><td>' + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Given + " " + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Family + "</td>";
let controlTime = 0;
let controlTimeDelta = 0;
for (let t = 0; t < controlArray.length; t++) {
if (typeof(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t])!== 'undefined'){
controlTime = parseInt(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t].Time, 10)-controlTimeDelta
controlTimeDelta += controlTime;
splitTimes += '<td>'+ TimeFormater(controlTime) +'<br>'+ TimeFormater(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t].Time)+'</td>'
}
else{
splitTimes += '<td><br></td>'
}
}
}
else if (typeof(xmlObj.ClassResult[i].PersonResult[k])!== 'undefined' && typeof(xmlObj.ClassResult[i].PersonResult[0].Result.SplitTime)!== 'undefined' && persStatus == 'MissingPunch'){
splitTimes += '<tr><td>' + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Given + " " + xmlObj.ClassResult[i].PersonResult[k].Person.Name.Family + "(DSQ)</td>";
let controlTimeDelta = 0;
for (let t = 0; t < controlArray.length; t++) {
if (typeof(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime)!== 'undefined'){
if (typeof(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t])!== 'undefined'){
if (typeof(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t].Time)!=='undefined'){
controlTime = parseInt(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t].Time, 10)-controlTimeDelta
controlTimeDelta += controlTime;
splitTimes += '<td>'+ TimeFormater(controlTime) +'<br>'+ TimeFormater(xmlObj.ClassResult[i].PersonResult[k].Result.SplitTime[t].Time)+'</td>'
}
else {splitTimes += '<td></td>'}
}}}
}
splitTimes += '</tr>';
}
}
resultTable += "</table></div>"
splitTimes += "</table></div>"
let pClassName = classesArray[i].replace(/ |\//g, "_");
let classTitle;
if(typeof(xmlObj.ClassResult[i].Course)!=="undefined"){
classTitle = '<h4>'+xmlObj.ClassResult[i].Class.Name+' ('+xmlObj.ClassResult[i].Course.Length+'m)</h4>'
}
else{
classTitle = '<h4>'+xmlObj.ClassResult[i].Class.Name+'</h4>'
}
resultTableA = '<div class="result-div">'+'<h4>'+xmlObj.ClassResult[i].Class.Name+'</h4>'+'<table class="ResultTable" id="'+classesArray[i]+'-table">'+'<tr class="table-labels"><td></td><td>Løper</td><td class="club-collum">Klubb</td><td>Tid</td><td>Diff</td></tr>'+resultTable;
let resultTableB = '<div class="result-header">'+classTitle+'<button class="fancy-button" onclick="showHideSplits(\''+pClassName+'\')">Vis/skjul Strekktider</button></div><div class="result-div"><table class="ResultTable" id="'+classesArray[i]+'-table">'+'<tr class="table-labels"><td></td><td>Løper</td><td class="club-collum">Klubb</td><td>Tid</td><td>Diff</td></tr>'+resultTable;
splitTimes = '<div class="result-div">'+splitTimes;
document.getElementById(pClassName).innerHTML = resultTableB+splitTimes;
sortTable(pClassName+'-table');
document.getElementById("alle-cont").innerHTML += '<div class="all-result-div">'+resultTableA.replace(/-table/g, "-all-table")+'</div>';
resultTable = "";
splitTimes = "";
}
//sets the variable that controls height of the all results flex
document.documentElement.style.setProperty('--row-count', rowCount * 1.8 + "rem");
}
};
xmlhttp.open("GET", "xmlToJson.php", true);
xmlhttp.send();
}
loadresults()
function mkDateStr(timestmp) {
var date = new Date(timestmp * 1000);
// Hours part from the timestamp
var hours = date.getHours();
// Minutes part from the timestamp
var minutes = "0" + date.getMinutes();
// Seconds part from the timestamp
var seconds = "0" + date.getSeconds();
// Will display time in 10:30:23 format
var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
return formattedTime;
}
var lastUpdate;
if (typeof(EventSource) !== "undefined") {
var source = new EventSource("updater.php");
source.onmessage = function(event) {
////console.log(event);
statusArray = event.data.split(",");
lastMessage = parseInt(statusArray[3], 10);
//console.log(statusArray);
document.getElementById("lastUpdate").innerHTML = "Siste oppdatering: " + mkDateStr(statusArray[1]);
document.getElementById("lastMessage").innerHTML = "Sist sjekket: " + mkDateStr(statusArray[2]);
updateInt = parseInt(statusArray[0], 10);
//console.log(updateInt);
//check if update has accured
if (parseInt(statusArray[1], 10) + 6 > parseInt(statusArray[2], 10)) {
updateInt = 1;
}
if (lastUpdate == undefined) {
window.lastUpdate == parseInt(statusArray[1], 10)
}
//console.log(statusArray);
//update results
if (updateInt == 1) {
loadresults()
//console.log("Update!!!!! :=)");
window.lastUpdate = parseInt(statusArray[1], 10);
//var jdata = JSON.parse(statusArray[3]);
} else {
//console.log("No update");
}
};
} else {
document.getElementById("serverStatus").innerHTML = "Sorry, your browser does not support server-sent events...";
}
const checkConnection = async function() {
cTime = Math.round(Date.now() / 1000);
if (cTime > lastMessage + 30) {
//mistet tilkobling
var element = document.getElementById("ConnectionAlert");
element.classList.remove("hiddendiv");
} else {
//fortsatt tilkoblet
var element = document.getElementById("ConnectionAlert");
element.classList.add("hiddendiv");
}
}
function showHideSplits(className) {
let x = document.getElementById(className+'-table');
let y = document.getElementById(className+'-splits');
if (x.style.display === "none") {
x.style.display = "table";
y.style.display = "none";
} else {
x.style.display = "none";
y.style.display = "table";
}
}
var interval = setInterval(checkConnection, 10000);
/*
if (window.location.hash) {
changeTab(window.location.hash.replace(/#tab-/g,''));
}
*/
// @license-end