291 lines
8.7 KiB
JavaScript
291 lines
8.7 KiB
JavaScript
function Controller(apikey, url) {
|
|
const apiKey = apikey; // Replace with your actual API key
|
|
const apiUrl = url ?? 'https://localhost:7005/api/Score'; // Replace with your API endpoint URL
|
|
console.log(apiKey);
|
|
var self = this;
|
|
//API poll variables
|
|
var INTERVAL = 5000;
|
|
var timeout = null;
|
|
var currentReq = null;
|
|
this.isConnected = ko.observable(false);
|
|
|
|
//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) => {
|
|
self.isConnected(false);
|
|
console.log(`Error Occurred retrieving data ${error}`);
|
|
})
|
|
.then(scheduleNewDataFetch);
|
|
};
|
|
|
|
var processResponse = function (response) {
|
|
if (!response.ok) {
|
|
self.isConnected(false);
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
self.isConnected(true);
|
|
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);
|
|
};
|
|
|
|
self.deleteEvent = function (id) {
|
|
console.log(`Call to delete event ${id}`);
|
|
fetch(`${apiUrl}/event/${id}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'x-api-key': apiKey
|
|
}
|
|
})
|
|
.then(fetchNewData);
|
|
};
|
|
|
|
var scheduleNewDataFetch = function () {
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
}
|
|
timeout = setTimeout(fetchNewData, INTERVAL);
|
|
};
|
|
|
|
self.getMatchPendingMessage = function () {
|
|
if (self.gameState() === "") {
|
|
return "No Match has been configured at this time.";
|
|
}
|
|
return `The match has not started yet.. Kick off is scheduled for ${self.kickOffTime()}.`;
|
|
};
|
|
|
|
self.addTeamEvent = function (team, evtType) {
|
|
const eventData = {
|
|
eventType: evtType,
|
|
category: team,
|
|
timeStamp: new Date().toISOString()
|
|
};
|
|
|
|
fetch(`${apiUrl}/${selectedTeam}`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-api-key': apiKey,
|
|
},
|
|
body: JSON.stringify(eventData),
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('Event data sent successfully:', data);
|
|
})
|
|
.catch(error => {
|
|
console.error('Error sending event data:', error);
|
|
});
|
|
};
|
|
|
|
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 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 }
|
|
}
|
|
|
|
self.disconnectedMessage = function() {
|
|
return `Unable to connect to server: ${apiUrl}`;
|
|
};
|
|
fetchNewData(); // Starts the update loop
|
|
}
|
|
|
|
var paramsString = window.location.search.split("?")[1];
|
|
var paramValues = paramsString.split("&");
|
|
var params = {};
|
|
paramValues.forEach((param) => {
|
|
var paramValue = param.split("=");
|
|
params[paramValue[0]] = paramValue[1];
|
|
});
|
|
|
|
ko.applyBindings(new Controller(params.apiKey, params.url)); |