Scoreboard/HTML/PublicScoreboardDetails/scoreboardDetails.js
2025-01-08 09:39:14 +00:00

241 lines
7.3 KiB
JavaScript

function ScoreboardDetails() {
const apiKey = '396A62D6-0192-4738-8F45-8AAF7BCFA3EC'; // Replace with your actual API key
const apiUrl = 'https://localhost:7005/api/Score'; // Replace with your API endpoint URL
const matchDuration = 80 * 60 * 1000;
var self = this;
//API poll variables
var INTERVAL = 5000;
var timeout = null;
var currentReq = null;
//knockout variables
this.gameState = ko.observable("");
this.half = ko.observable("Pre");
this.kickOffTime = ko.observable(new Date());
this.gameOn = ko.observable(false);
this.eventList = ko.observableArray([]);
this.homeTeamName = ko.observable("Uckfield RFC");
this.homeTeamColor = ko.observable("#ff0000");
this.homeTeamPoints = ko.observable(0);
this.homeTeamLogo = ko.observable("");
this.awayTeamName = ko.observable("Away team");
this.awayTeamColor = ko.observable("#0000ff");
this.awayTeamPoints = ko.observable(0);
this.awayTeamLogo = ko.observable("");
self.calculateRemainingTime = ko.computed(function () {
if (self.half() === 'Pre') { return "---"; }
if (self.gameState() === 'HalfTime') { return '40:00'; }
if (self.gameState() === 'Finished') { return '80:00'; }
return calc();
});
var isSecondHalfEvent=function(matchEvts){
return !!matchEvts.find(e=>e.eventType === 'SecondHalfStart');
};
var calc = function (eventId = 0, minsOnly=false) {
var matchEvts = self.eventList().filter(x => (x.category === 'Match' && x.id <= eventId) || x.id === eventId);
var initialTime = self.kickOffTime(); //IF FIRST HALF, WORK OUT FOR IF SECOND HALF
var halfStart = self.kickOffTime();
var offsetMins = 0;
if ((eventId != 0 &&isSecondHalfEvent(matchEvts))
|| (eventId == 0 && self.half() === 'Second')) {
var secondHalfEvent = self.eventList().find(x => x.eventType === 'SecondHalfStart');
if (!secondHalfEvent) {
throw 'Invalid System Event State, Second Half without Second Half Event';
}
halfStart = new Date(secondHalfEvent.timeStamp);
initialTime = new Date(secondHalfEvent.timeStamp);
offsetMins = 40;
matchEvts = self.eventList().filter(x=>x.id >= secondHalfEvent.id && (x.category === 'Match' || x.id === eventId))
}
if (!matchEvts || matchEvts.length <= 1) {
const diff = calcDiff(initialTime, new Date());
return `${String(diff.mins + offsetMins).padStart(2, "0")}:${String(diff.secs).padStart(2, "0")}`
}
var totalMins = offsetMins;
var totalSecs = 0;
matchEvts.forEach((evt, idx, src) => {
if (eventId === 0 || evt.id <= eventId) {
if (evt.eventType === 'TimeOff') {
var t = calcDiff(initialTime, new Date(evt.timeStamp));
totalMins += t.mins;
totalSecs += t.secs;
}
if (evt.eventType === 'TimeOn') {
initialTime = new Date(evt.timeStamp);
if(idx === (src.length-1)){
var t = calcDiff(new Date(evt.timeStamp), new Date());
totalMins += t.mins;
totalSecs += t.secs;
}
}
if (eventId != 0 && eventId === evt.id) {
var t = calcDiff(initialTime, new Date(evt.timeStamp));
totalMins += t.mins;
totalSecs += t.secs;
}
}
});
if (totalSecs >= 60) {
totalMins += 1;
totalSecs = totalSecs % 60;
}
if(minsOnly){
return `${String(totalMins).padStart(2, "0")}`;
}
return `${String(totalMins).padStart(2, "0")}:${String(totalSecs).padStart(2, "0")}`;
}
self.halfIndicator = ko.computed(function () {
const gameState = self.gameState();
if (gameState === "WaitingForStart") {
var dt = self.kickOffTime();
return `${String(dt.getHours()).padStart(2, "0")}:${String(dt.getMinutes()).padStart(2, "0")} KO`;
}
if (gameState === "FirstHalf") {
return "1st Half";
}
if (gameState === "SecondHalf") {
return "2nd Half";
}
if (gameState === "TimeOff") {
return "Time Off";
}
});
var fetchNewData = function () {
currentReq = fetch(apiUrl, {
method: 'GET',
headers: {
'x-api-key': apiKey
},
});
currentReq
.then(processResponse)
.then(processJson)
.catch((error) => console.log(`Error Occurred retrieving data ${error}`))
.then(scheduleNewDataFetch);
};
var processResponse = function (response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
if (response.status === 204) {
self.gameOn(false);
INTERVAL = 60000;
return Promise.reject('no game');
}
INTERVAL = 5000;
return response.json();
};
var processJson = function (data) {
self.eventList(data.eventHistory);
self.gameOn(true);
self.gameState(data.state);
self.half(data.half);
self.kickOffTime(new Date(data.startedAt));
self.homeTeamName(data.home.name);
self.awayTeamName(data.away.name);
self.homeTeamPoints(data.home.points);
self.awayTeamPoints(data.away.points);
};
var scheduleNewDataFetch = function () {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(fetchNewData, INTERVAL);
};
self.getEventMessage = function (evt) {
var eventMins = self.getEventTime(evt);
var eventMsg = parseEventType(evt.eventType);
if (evt.category !== "Match") {
if (evt.eventType === "YellowCard" || evt.eventType === "RedCard") {
return `${eventMins} mins: ${eventMsg}`;
}
return `${eventMins} mins: ${eventMsg} Scored`;
}
return `${eventMsg}`;
}
self.getScoreAtEvent = function (evtId) {
var evts = self.eventList();
var homeScore = 0;
var awayScore = 0;
evts.forEach(evt => {
if (evt.id <= evtId) {
if (evt.category === 'Home') {
homeScore += evt.points;
} else {
awayScore += evt.points;
}
}
});
return `${homeScore} - ${awayScore}`;
}
self.getEventTime = function (evt) {
if (evt.category === 'Match') { return; }
let t = calc(evt.id, true);
return t;
var eventDate = new Date(evt.timeStamp);
var diffMs = eventDate - self.kickOffTime();
var timeMins = Math.round(((diffMs % 86400000) % 3600000) / 60000);
return timeMins;
}
var parseEventType = function(evtType){
switch (evtType) {
case 'DropGoal':
return 'Drop Goal';
case 'HalfTime':
return 'Half Time';
case 'MatchStart':
return 'Match Start';
case 'SecondHalfStart':
return 'Second Half Start';
case 'TimeOff':
return 'Time Off';
case 'TimeOn':
return 'Time On';
case 'YellowCard':
return 'Yellow Card';
case 'RedCard':
return 'Red Card';
case 'MatchEnd':
return 'Full Time';
default:
return evtType;
}
}
var calcDiff = function (startTimeStamp, endTimeStamp) {
var diff = endTimeStamp - startTimeStamp;
const minutes = Math.floor(diff / 60000);
const seconds = Math.floor((diff % 60000) / 1000);
return { mins: minutes, secs: seconds }
}
fetchNewData(); // Starts the update loop
}
ko.applyBindings(new ScoreboardDetails());