diff --git a/scoreboard/bin/www b/scoreboard/bin/www index 95be052..eec0010 100644 --- a/scoreboard/bin/www +++ b/scoreboard/bin/www @@ -12,7 +12,7 @@ var http = require('http'); * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || '3000'); +var port = normalizePort(process.env.PORT || '80'); app.set('port', port); /** diff --git a/scoreboard/controllers/cli.js b/scoreboard/controllers/cli.js index 0e3788b..4943376 100644 --- a/scoreboard/controllers/cli.js +++ b/scoreboard/controllers/cli.js @@ -1,23 +1,37 @@ -// CLI-Controller (Testdatei) -// Zuständig für die Verarbeitung von Kommandozeilen-Befehlen des Scoreboards. -// Aktuell nur ein Funktionstest mit einem einfachen `ls`-Befehl. +// CLI-Controller +// Startet und beendet den Anzeige-Browser auf dem Monitor-Rechner (Raspberry Pi). +// Chromium wird im Kiosk-Modus auf Display :0 geöffnet und zeigt die Monitor-Ansicht an. -const exec = require('node:child_process'); +const { spawn } = require('node:child_process') -// Testaufruf: Listet den Inhalt des aktuellen Verzeichnisses auf, -// um zu prüfen, ob child_process.exec korrekt funktioniert. -exec('ls ./', (err, output) => { - if (err) { - console.error("could not execute command: ", err) - return +let command; // Referenz auf den laufenden Chromium-Prozess +let browserOpen = false; // Status des Browsers, verhindert Mehrfachstart + +// Startet Chromium im Kiosk-Modus, sofern noch kein Browser laeuft +async function openBrowser() { + if(!browserOpen) { + // Als Benutzer "pi" starten, damit der Prozess Zugriff auf das X-Display hat + command = spawn('sudo', ['-upi', 'chromium-browser', '--display=:0', '--incognito', '--noerrors', '--hide-crash-restore-bubble', '--disable-infobars', '--kiosk', 'http://localhost']); + + command.stdout.on('data', data => { + console.log("stdout: ", data.toString()); + }); + + command.stderr.on('data', data => { + console.log("sterr: ", data.toString()); + }); + browserOpen = true; } - console.log("Output: \n", output) -}) - - - - - - +} +// Beendet den laufenden Browserprozess, sofern einer gestartet wurde +async function killBrowser() { + if(browserOpen) { + command.kill(); + browserOpen = false; + } +} +module.exports = { + openBrowser, killBrowser +} diff --git a/scoreboard/controllers/db.js b/scoreboard/controllers/db.js new file mode 100644 index 0000000..a135404 --- /dev/null +++ b/scoreboard/controllers/db.js @@ -0,0 +1,46 @@ +"use strict"; + +let db; + +// Import ESM into CJS file using immediately invoked function expression because of missing top-level await in CJS +(async () => { + const { LowSync } = await import('lowdb'); + const { JSONFileSync } = await import('lowdb/node'); + db = new LowSync(new JSONFileSync('db.json'), { teams: []}) +})(); + +function getTeams() { + db.read(); + return db.data.teams +} + +// Adds passed teamName to db if not already existing +function addTeam(teamName) { + console.log(teamName) + db.read(); + if(!db.data.teams.includes(teamName) && teamName != "") { // Teamname not in db + db.data.teams.push(teamName); + db.write(); + } else { // Teamname already in db + } +} + +// Deletes passed teamName from db if existing +function deleteTeam(teamName) { + db.read(); + if(db.data.teams.includes(teamName) && teamName != "") { // Teamname in db + db.data.teams.splice(db.data.teams.indexOf(teamName), 1) // Delete corresponding array entry + db.write(); + } +} + +// Returns important values from db +function getValues() { + db.read(); + console.log(db.data) + return db.data +} + +module.exports = { + getTeams, addTeam, deleteTeam, getValues +} \ No newline at end of file diff --git a/scoreboard/controllers/etc.js b/scoreboard/controllers/etc.js new file mode 100644 index 0000000..146142d --- /dev/null +++ b/scoreboard/controllers/etc.js @@ -0,0 +1,21 @@ +let splashscreenEnabled = true; + +// Toggles a splashscreen +function toggleSplashScreen() { + splashscreenEnabled = !splashscreenEnabled; +} + +// Returns splashscreen enabled attribute +function getSplashscreen() { + return splashscreenEnabled; +} + +function getValues() { + return { + splashscreenEnabled: splashscreenEnabled, + } +} + +module.exports = { + toggleSplashScreen, getSplashscreen, getValues +} \ No newline at end of file diff --git a/scoreboard/controllers/score.js b/scoreboard/controllers/score.js index 6e0ba7c..1bdefe0 100644 --- a/scoreboard/controllers/score.js +++ b/scoreboard/controllers/score.js @@ -1,6 +1,7 @@ const io = require('./socketio'); +const db = require('../controllers/db'); -let enabled = false; +let enabled = true; let teamA = { name: "Team A", name2: "", @@ -13,7 +14,8 @@ let teamB = { score: 0, isSpielgemeinschaft: 0, }; -let sideswitch = false; +let sideswitch = false; // Attribute to switch sides after halftime +let referenceMirrored = false; // If sitting behind the scoreboard, switch sides for admin board // Funktionsübersicht (Prototypen ohne Implementierung — nur zur Übersicht) function setEnabled(status) {}; @@ -21,7 +23,7 @@ function configTeam(team, name, name2, isSpielgemeinschaft) {}; function setScore(team, score) {}; function alterScore(team, dir) {}; function clearScore() {}; -function toggleSideSwitch() {}; +function toggleSideswitch() {}; function getEnabled() {}; function getValues() {}; @@ -91,6 +93,11 @@ function toggleSideswitch() { io.sockets.emit('scoreSideswitch', ''); } +// Mirror team position on admin panel +function toggleReferenceMirrored() { + referenceMirrored = !referenceMirrored; +} + // Return enabled value function getEnabled() { return enabled @@ -112,10 +119,12 @@ function getValues() { teamA: teamA, teamB: teamB, sideswitch: sideswitch, + referenceMirrored: referenceMirrored, print: print(), + teams: db.getTeams(), }; } module.exports = { - setEnabled, configTeam, setScore, alterScore, clearScore, toggleSideswitch, getEnabled, getValues + setEnabled, configTeam, setScore, alterScore, clearScore, toggleSideswitch, toggleReferenceMirrored, getEnabled, getValues, } \ No newline at end of file diff --git a/scoreboard/db.json b/scoreboard/db.json new file mode 100644 index 0000000..8d95e21 --- /dev/null +++ b/scoreboard/db.json @@ -0,0 +1,12 @@ +{ + "teams": [ + "Arheilgen", + "Prechtal", + "RVW Merklingen", + "Hofen", + "Leeden", + "Oelde", + "Burgkunstadt", + "Gaustadt" + ] +} \ No newline at end of file diff --git a/scoreboard/package-lock.json b/scoreboard/package-lock.json index 5e9c263..4eea9ad 100644 --- a/scoreboard/package-lock.json +++ b/scoreboard/package-lock.json @@ -14,6 +14,7 @@ "express-ws": "^5.0.2", "hbs": "~4.0.4", "http-errors": "~1.6.3", + "lowdb": "^7.0.1", "moment": "^2.30.1", "morgan": "~1.9.1", "socket.io": "^4.7.5", @@ -469,6 +470,20 @@ "node": ">= 0.10" } }, + "node_modules/lowdb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz", + "integrity": "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==", + "dependencies": { + "steno": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -843,6 +858,17 @@ "node": ">= 0.6" } }, + "node_modules/steno": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/steno/-/steno-4.0.2.tgz", + "integrity": "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", diff --git a/scoreboard/package.json b/scoreboard/package.json index 458b6c4..63f7a92 100644 --- a/scoreboard/package.json +++ b/scoreboard/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "nodemon ./bin/www" + "start": "nodemon --ignore '*.json' ./bin/www" }, "dependencies": { "cookie-parser": "~1.4.4", @@ -12,6 +12,7 @@ "express-ws": "^5.0.2", "hbs": "~4.0.4", "http-errors": "~1.6.3", + "lowdb": "^7.0.1", "moment": "^2.30.1", "morgan": "~1.9.1", "socket.io": "^4.7.5", diff --git a/scoreboard/public/img/SG_Arheilgen.png b/scoreboard/public/img/SG_Arheilgen.png new file mode 100644 index 0000000..e4b7fc2 Binary files /dev/null and b/scoreboard/public/img/SG_Arheilgen.png differ diff --git a/scoreboard/public/img/SG_Arheilgen_upscaled.png b/scoreboard/public/img/SG_Arheilgen_upscaled.png new file mode 100644 index 0000000..3b42d40 Binary files /dev/null and b/scoreboard/public/img/SG_Arheilgen_upscaled.png differ diff --git a/scoreboard/public/javascripts/admin.js b/scoreboard/public/javascripts/admin.js index c6b7492..1036eec 100644 --- a/scoreboard/public/javascripts/admin.js +++ b/scoreboard/public/javascripts/admin.js @@ -20,13 +20,28 @@ socket.on('timerEnded', (message) => { socket.on('score', (message) => { console.log(message); // Log score in client console - document.getElementById("score").innerHTML = message; // Display score in corresponding html Element + scoreGetValues(); + // document.getElementById("score").innerHTML = message; // Display score in corresponding html Element }); // ###################################################################################################################################################### // General functions // ###################################################################################################################################################### +// Initial update gets called whenever page has been loaded +async function initialUpdate() { + etcGetValues(); // Request new values for etc stuff + timerGetValues(); // Request new values for timer + scoreGetValues(); // Request new values for score + dbGetValues(); // Request new values for db contents +} + +// Update DOM timer elements from passed values +function updateEtcFrontend(values) { + console.log(values); + document.getElementById("etcSwitchEnable").checked = values.splashscreenEnabled;// Set switch status to received score enabled value +} + // Update DOM timer elements from passed values function updateTimerFrontend(values) { console.log(values); // Print received data @@ -43,13 +58,22 @@ function updateTimerFrontend(values) { } } +// Build colname to show Teams on Adminpanel based on isSpielgemeinschaft +function buildColFromIsSpielgemeinschaft(team) { + if(team.isSpielgemeinschaft) { + return team.name + "
" + team.name2; + } else { + return team.name + "
 "; + } +} + // Update DOM score elements from passed values function updateScoreFrontend(values) { console.log(values); // Print received data document.getElementById("scoreSwitchEnable").checked = values.enabled; // Set switch status to received score enabled value - document.getElementById("score").innerHTML = values.print; // Set score on admin interface + document.getElementById("scoreSwitchReferenceMirrored").checked = values.referenceMirrored; // Set switch status to received score enabled value - // Input current Team values into form inputs + // Config Teams - Input current teams into text fields document.getElementById("teamAname").value = values.teamA.name; document.getElementById("teamAname2").value = values.teamA.name2; document.getElementById("teamAisSpielgemeinschaft").checked = values.teamA.isSpielgemeinschaft; @@ -57,12 +81,88 @@ function updateScoreFrontend(values) { document.getElementById("teamBname").value = values.teamB.name; document.getElementById("teamBname2").value = values.teamB.name2; document.getElementById("teamBisSpielgemeinschaft").checked = values.teamB.isSpielgemeinschaft; + + // Show current Teams on admin panel + if(!values.referenceMirrored && !values.sideswitch || values.referenceMirrored && values.sideswitch) { // If not mirrored on adminpanel, show like main frontend while considering sideswitch state + document.getElementById("score").innerHTML = values.teamA.score + ':' + values.teamB.score; + document.getElementById("teamAcolName").innerHTML = buildColFromIsSpielgemeinschaft(values.teamA); + document.getElementById("teamBcolName").innerHTML = buildColFromIsSpielgemeinschaft(values.teamB); + document.getElementById("teamAinc").setAttribute("onclick", "scoreAlterScore('teamA', 'inc')"); + document.getElementById("teamAdec").setAttribute("onclick", "scoreAlterScore('teamA', 'dec')"); + document.getElementById("teamBinc").setAttribute("onclick", "scoreAlterScore('teamB', 'inc')"); + document.getElementById("teamBdec").setAttribute("onclick", "scoreAlterScore('teamB', 'dec')"); + + } else if(!values.referenceMirrored && values.sideswitch || values.referenceMirrored && !values.sideswitch) { // Else, swap posistions + document.getElementById("score").innerHTML = values.teamB.score + ':' + values.teamA.score; + document.getElementById("teamAcolName").innerHTML = buildColFromIsSpielgemeinschaft(values.teamB); + document.getElementById("teamBcolName").innerHTML = buildColFromIsSpielgemeinschaft(values.teamA); + document.getElementById("teamAinc").setAttribute("onclick", "scoreAlterScore('teamB', 'inc')"); + document.getElementById("teamAdec").setAttribute("onclick", "scoreAlterScore('teamB', 'dec')"); + document.getElementById("teamBinc").setAttribute("onclick", "scoreAlterScore('teamA', 'inc')"); + document.getElementById("teamBdec").setAttribute("onclick", "scoreAlterScore('teamA', 'dec')"); + } + } -// Initial update gets called whenever page has been loaded -async function initialUpdate() { - timerGetValues(); // Request new values for timer - scoreGetValues(); // Request new values for score +// Update DOM for all db contents with the passed values +function updateDbFrontend(values) { + console.log(values); + + let teamAnameDropdown = document.getElementById("teamAnameDropdown"); // Dropdown for TeamA name + let teamAname2Dropdown = document.getElementById("teamAname2Dropdown"); // Dropdown for TeamA name2 + let teamBnameDropdown = document.getElementById("teamBnameDropdown"); // Dropdown for TeamB name + let teamBname2Dropdown = document.getElementById("teamBname2Dropdown"); // Dropdown for TeamB name2 + + // Clear innerHTML of dropdowns + teamAnameDropdown.innerHTML = ""; + teamAname2Dropdown.innerHTML = ""; + teamBnameDropdown.innerHTML = ""; + teamBname2Dropdown.innerHTML = ""; + + let selectDelete = document.getElementById("dbTeamToDelete"); // Select for team deletion from db + selectDelete.innerHTML = "" // Clears all existing options from select + + //
  • Action
  • + + for(team of values.teams) { + // Create custom Dropdowns with different function arguments for team configuration + var li = document.createElement("li"); + li.innerHTML = ` `+ team +``; + teamAnameDropdown.appendChild(li); + var li = document.createElement("li"); + li.innerHTML = ` `+ team +``; + teamAname2Dropdown.appendChild(li); + var li = document.createElement("li"); + li.innerHTML = ` `+ team +``; + teamBnameDropdown.appendChild(li); + var li = document.createElement("li"); + li.innerHTML = ` `+ team +``; + teamBname2Dropdown.appendChild(li); + + // Create select options for deletion in debugwindow + let opt = document.createElement("option"); + opt.value = team; + opt.innerHTML = team; + selectDelete.appendChild(opt); + } +} + +// Inserts the passed name into the passed name text input +async function scoreInsertChosenName(field, name) { + switch(field) { + case 'teamAname': + document.getElementById("teamAname").value = name; + break; + case 'teamAname2': + document.getElementById("teamAname2").value = name; + break; + case 'teamBname': + document.getElementById("teamBname").value = name; + break; + case 'teamBname2': + document.getElementById("teamBname2").value = name; + break; + } } // Request monitor refresh for index frontend @@ -70,6 +170,33 @@ async function refreshMonitor() { const response = await fetch("/admin/refreshMonitor"); // Call API Endpoint /admin/timerStart } +async function openBrowser() { + const response = await fetch("/admin/openBrowser"); // Call API Endpoint /admin/openBrowser +} + +async function killBrowser() { + const response = await fetch("/admin/killBrowser"); // Call API Endpoint /admin/killBrowser +} + +// ###################################################################################################################################################### +// Etc endpoints +// ###################################################################################################################################################### + +// Request important values for etc stuff +async function etcGetValues() { + const response = await fetch("/admin/etcGetValues"); // Call API Endpoint /admin/etcGetValues + const data = await response.json(); // Wait for asynchronous transfer to complete + updateEtcFrontend(data); // Update admin frontend +} + +// Toggle index page to also show scoreboard +async function etcToggleSplashscreen() { + const response = await fetch("/admin/etcToggleSplashscreen");// Call API Endpoint /admin/etcToggleSplashscreen + const data = await response.json(); // Wait for asyncronous transfer to complete + updateEtcFrontend(data); // Update admin frontend + refreshMonitor(); // Refresh main monitor to display new frontend +} + // ###################################################################################################################################################### // Timerfunctions // ###################################################################################################################################################### @@ -165,6 +292,13 @@ async function scoreToggleSideswitch() { updateScoreFrontend(data); // Update admin frontend } +// Switch sides to mirror admin panel when sitting behind main monitor +async function scoreToggleReferenceMirrored() { + const response = await fetch("/admin/scoreToggleReferenceMirrored");// Call API Endpoint /admin/scoreSwitch + const data = await response.json(); // Wait for asyncronous transfer to complete + updateScoreFrontend(data); // Update admin frontend +} + // Clear score async function scoreClearScore() { const response = await fetch("/admin/scoreClearScore"); // Call API Endpoint /admin/scoreClearScore @@ -194,4 +328,39 @@ async function scoreConfigTeams() { const data = await response.json(); // Wait for asyncronous transfer to complete updateScoreFrontend(data); // Update admin frontend refreshMonitor(); +} + +// ###################################################################################################################################################### +// DB functions +// ###################################################################################################################################################### + +// Request important values for db contents +async function dbGetValues() { + const response = await fetch("/admin/dbGetValues"); // Call API Endpoint /admin/dbGetValues + const data = await response.json(); // Wait for asynchronous transfer to complete + updateDbFrontend(data); // Update admin frontend +} + +// Add team to DB +async function dbAddTeam() { + const response = await fetch("/admin/dbAddTeam", { // Call API Endpoint /admin/scoreAlterScore with the teamname to alter the score in the specified direction + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({teamName: document.getElementById("dbTeamToAdd").value}) + }); + document.getElementById("dbTeamToAdd").value = ""; // Empty the text field after sending + const data = await response.json(); // Wait for asyncronous transfer to complete + updateDbFrontend(data); +} + +// Delete team from DB +async function dbDeleteTeam() { + let teamName = document.getElementById("dbTeamToDelete").value; + const response = await fetch("/admin/dbDeleteTeam", { // Call API Endpoint /admin/scoreAlterScore with the teamname to alter the score in the specified direction + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({teamName: teamName}) + }); + const data = await response.json(); // Wait for asyncronous transfer to complete + updateDbFrontend(data); } \ No newline at end of file diff --git a/scoreboard/public/javascripts/splashscreen.js b/scoreboard/public/javascripts/splashscreen.js new file mode 100644 index 0000000..3053f07 --- /dev/null +++ b/scoreboard/public/javascripts/splashscreen.js @@ -0,0 +1,14 @@ +let wss = "ws://" + window.location.hostname + ":3001" // Build socketio endpoint from window.location +const socket = io(wss); // Connect to socketio server + +// ###################################################################################################################################################### +// Websockets event handler +// ###################################################################################################################################################### + +socket.on('connected', (message) => { + console.log("Connected"); +}); + +socket.on('refresh', (message) => { + document.location.reload() // Reload page on received 'refresh' messagen +}); \ No newline at end of file diff --git a/scoreboard/public/stylesheets/indexScore.css b/scoreboard/public/stylesheets/indexScore.css index 05bf585..ce71bdc 100644 --- a/scoreboard/public/stylesheets/indexScore.css +++ b/scoreboard/public/stylesheets/indexScore.css @@ -26,6 +26,10 @@ a { font-size: 50vh } +.teamName { + font-size: 10vh +} + @media ( min-width: 768px ) { .box-time { height:25% diff --git a/scoreboard/public/stylesheets/splashscreen.css b/scoreboard/public/stylesheets/splashscreen.css new file mode 100644 index 0000000..e69de29 diff --git a/scoreboard/routes/admin.js b/scoreboard/routes/admin.js index cf611f4..02dcfab 100644 --- a/scoreboard/routes/admin.js +++ b/scoreboard/routes/admin.js @@ -4,6 +4,9 @@ const io = require('../controllers/socketio'); const timer = require('../controllers/timer'); const score = require('../controllers/score'); +const cli = require('../controllers/cli'); +const db = require('../controllers/db'); +const etc = require('../controllers/etc'); // ###################################################################################################################################################### // General endpoints @@ -17,12 +20,37 @@ router.get('/refreshMonitor', function(req, res, next) { res.send(); // send empty response }); -// Express router endpoint to do cli stuff -router.get('/cli', function(req, res, next) { +// Express router endpoint to open browser +router.get('/openBrowser', function(req, res, next) { + cli.openBrowser(); res.status(200); // Set http status code to 200 (success) res.send(); // send empty response }); +// Express router endpoint to kill browser +router.get('/killBrowser', function(req, res, next) { + cli.killBrowser(); + res.status(200); // Set http status code to 200 (success) + res.send(); // send empty response +}); + +// ###################################################################################################################################################### +// Etc endpoints +// ###################################################################################################################################################### + +// Express router endpoint to toggle splashscreen +router.get('/etcToggleSplashscreen', function(req, res, next) { + etc.toggleSplashScreen(); // Toggles splashscreen + res.status(200); // Set http status code to 200 (success) + res.json(etc.getValues()); // Answer with important values +}); + +// Express router endpoint to get important etc values +router.get('/etcGetValues', function(req, res, next) { + res.status(200); // Set http status code to 200 (success) + res.json(etc.getValues()); // Answer with important values +}); + // ###################################################################################################################################################### // Timerendpoints // ###################################################################################################################################################### @@ -106,6 +134,13 @@ router.get('/scoreToggleSideswitch', function(req, res, next) { res.json(score.getValues()); }); +// Express router endpoint to toggle reference mirrored attribute +router.get('/scoreToggleReferenceMirrored', function(req, res, next) { + score.toggleReferenceMirrored(); + res.status(200); + res.json(score.getValues()); +}); + // Express router endpoint to get important score values router.get('/scoreGetValues', function(req, res, next) { res.json(score.getValues()); // Respond with important values for frontend @@ -125,6 +160,27 @@ router.post('/scoreConfigTeams', function(req, res, next) { res.json(score.getValues()); }); +// ###################################################################################################################################################### +// DB endpoints +// ###################################################################################################################################################### + +// Express router endpoint to get important values for db contents +router.get('/dbGetValues', function(req, res, next) { + res.json(db.getValues()); // Respond with important values for frontend +}); + +// Express router endpoint to add a team to the team database +router.post('/dbAddTeam', function(req, res, next) { + db.addTeam(req.body.teamName); // Add teamname to DB + res.json(db.getValues()); // Respond with all important values to update the frontend +}); + +// Express router endpoint to delete a team from the team database +router.post('/dbDeleteTeam', function(req, res, next) { + db.deleteTeam(req.body.teamName); // Add teamname to DB + res.json(db.getValues()); // Respond with all important values to update the frontend +}); + /* GET home page. */ router.get('/', function(req, res, next) { res.render('admin'); diff --git a/scoreboard/routes/index.js b/scoreboard/routes/index.js index 4aa1a41..70d56ab 100644 --- a/scoreboard/routes/index.js +++ b/scoreboard/routes/index.js @@ -2,14 +2,19 @@ var express = require('express'); var router = express.Router(); let io = require('../controllers/socketio'); -const score = require("../controllers/score"); +const score = require('../controllers/score'); +const etc = require('../controllers/etc'); /* GET home page. */ router.get('/', function(req, res, next) { - if (score.getEnabled()) { // If scoreboard is enabled - res.render('indexScore', {}); // Render the site with scoreboard - } else { // If scoreboard is not enabled - res.render('index', {}); // Render the site without scoreboard + if(etc.getSplashscreen()) { // If splashscreen is enabled + res.render('splashscreen', {}); // Render splashscreen + } else { + if (score.getEnabled()) { // If scoreboard is enabled + res.render('indexScore', {}); // Render the site with scoreboard + } else { // If scoreboard is not enabled + res.render('index', {}); // Render the site without scoreboard + } } }); diff --git a/scoreboard/views/admin.hbs b/scoreboard/views/admin.hbs index 781588c..b14274a 100644 --- a/scoreboard/views/admin.hbs +++ b/scoreboard/views/admin.hbs @@ -10,7 +10,7 @@ -
    +
    @@ -26,13 +26,13 @@
    - - + +
    -
    +
    @@ -47,7 +47,7 @@
    -
    +
    -
    +
    -

    +
    +
    +
    +
    + + +
    +
    +
    +

    +
    +
    +
    +
    + + +
    +
    +
    @@ -73,17 +91,13 @@
    -
    -
    - - -
    +
    +
    +
    -
    - - -
    +
    +
    @@ -93,9 +107,9 @@
    - + + -
    @@ -103,13 +117,7 @@
    -
    - - -
    - - - +
    @@ -239,34 +247,49 @@