mirror of https://github.com/dirtbags/moth.git
New scoreboard view
This commit is contained in:
parent
c4bf25f8fa
commit
63881f05fa
|
@ -492,9 +492,7 @@ class State {
|
|||
* @returns {Scores}
|
||||
*/
|
||||
CurrentScores() {
|
||||
let scores
|
||||
for (scores of this.ScoreHistory());
|
||||
return scores
|
||||
return [...this.ScoresHistory()].pop()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,4 +674,5 @@ class Server {
|
|||
export {
|
||||
Hash,
|
||||
Server,
|
||||
State,
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scoreboard</title>
|
||||
<link rel="stylesheet" href="basic.css">
|
||||
<link rel="stylesheet" href="scoreboard.css">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="icon" href="luna-moth.svg">
|
||||
<script type="module" src="scoreboard.mjs"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="no-scores hidden"></div>
|
||||
<div class="rotate">
|
||||
<div class="rankings category"></div>
|
||||
<div class="rankings classic"></div>
|
||||
</div>
|
||||
<div class="location"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -33,32 +33,37 @@
|
|||
max-height: 60vh;
|
||||
}
|
||||
|
||||
/* Only the first child of a rotate class is visible */
|
||||
.rotate > div:nth-child(n + 2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** Scoreboard */
|
||||
.rankings {
|
||||
.rankings.classic {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-color: #000c;
|
||||
}
|
||||
.rankings div {
|
||||
.rankings.classic div {
|
||||
height: 1.2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.rankings div:nth-child(6n){
|
||||
.rankings.classic div:nth-child(6n){
|
||||
background-color: #ccc3;
|
||||
}
|
||||
.rankings div:nth-child(6n+3) {
|
||||
.rankings.classic div:nth-child(6n+3) {
|
||||
background-color: #0f03;
|
||||
}
|
||||
|
||||
.rankings span {
|
||||
.rankings.classic span {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.rankings span.category {
|
||||
.rankings.classic span.category {
|
||||
font-size: 80%;
|
||||
}
|
||||
.rankings span.teamname {
|
||||
.rankings.classic span.teamname {
|
||||
height: auto;
|
||||
font-size: inherit;
|
||||
color: white;
|
||||
|
@ -67,8 +72,8 @@
|
|||
position: absolute;
|
||||
right: 0.2em;
|
||||
}
|
||||
.rankings span.teamname:hover,
|
||||
.rankings span.category:hover {
|
||||
.rankings.classic span.teamname:hover,
|
||||
.rankings.classic span.category:hover {
|
||||
width: inherit;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
@ -78,8 +83,24 @@
|
|||
vertical-align: top;
|
||||
}
|
||||
|
||||
.rankings.category {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
.rankings.category div {
|
||||
border: solid black 2px;
|
||||
min-width: 15em;
|
||||
}
|
||||
.rankings.category table {
|
||||
width: 100%;
|
||||
}
|
||||
.rankings.category td.number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 450px) {
|
||||
.rankings span.teamname {
|
||||
.rankings.classic span.teamname {
|
||||
max-width: 6em;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div class="no-scores hidden"></div>
|
||||
<div class="rankings"></div>
|
||||
<div class="rankings classic"></div>
|
||||
<div class="location"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -34,22 +34,39 @@ async function update() {
|
|||
}
|
||||
|
||||
// Pull configuration settings
|
||||
let ScoreboardConfig = config.Scoreboard ?? {}
|
||||
let ReplayHistory = ScoreboardConfig.ReplayHistory ?? false
|
||||
let ReplayDurationMS = ScoreboardConfig.ReplayDurationMS ?? 300
|
||||
let ReplayFPS = ScoreboardConfig.ReplayFPS ?? 24
|
||||
if (!config.Scoreboard) {
|
||||
console.warn("config.json has empty Scoreboard section")
|
||||
}
|
||||
|
||||
let ScoreboardConfig = config.Scoreboard ?? {}
|
||||
let state = await server.GetState()
|
||||
|
||||
// Show URL of server
|
||||
for (let e of document.querySelectorAll(".location")) {
|
||||
e.textContent = common.BaseURL
|
||||
e.classList.toggle("hidden", !(ScoreboardConfig.DisplayServerURLWhenEnabled && state.Enabled))
|
||||
}
|
||||
|
||||
let rankingsElement = document.querySelector(".rankings")
|
||||
// Rotate views
|
||||
for (let e of document.querySelectorAll(".rotate")) {
|
||||
e.appendChild(e.firstChild)
|
||||
}
|
||||
|
||||
// Render rankings
|
||||
for (let e of document.querySelectorAll(".rankings")) {
|
||||
if (e.classList.contains("classic")) {
|
||||
classicRankings(e, state, ScoreboardConfig)
|
||||
} else if (e.classList.contains("category")) {
|
||||
categoryRankings(e, state, ScoreboardConfig)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function classicRankings(rankingsElement, state, ScoreboardConfig) {
|
||||
let ReplayHistory = ScoreboardConfig.ReplayHistory ?? false
|
||||
let ReplayDurationMS = ScoreboardConfig.ReplayDurationMS ?? 300
|
||||
let ReplayFPS = ScoreboardConfig.ReplayFPS ?? 24
|
||||
|
||||
let logSize = state.PointsLog.length
|
||||
|
||||
// Figure out the timing so that we can replay the scoreboard in about
|
||||
|
@ -78,7 +95,7 @@ async function update() {
|
|||
|
||||
let topScore = scores.CyFiScore(sortedTeamIDs[0])
|
||||
for (let teamID of sortedTeamIDs) {
|
||||
let teamName = state.TeamNames[teamID]
|
||||
let teamName = state.TeamNames[teamID] ?? "rodney"
|
||||
|
||||
let row = rankingsElement.appendChild(document.createElement("div"))
|
||||
|
||||
|
@ -118,6 +135,46 @@ async function update() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} rankingsElement
|
||||
* @param {moth.State} state
|
||||
* @param {*} ScoreboardConfig
|
||||
*/
|
||||
async function categoryRankings(rankingsElement, state, ScoreboardConfig) {
|
||||
while (rankingsElement.firstChild) rankingsElement.firstChild.remove()
|
||||
let scores = state.CurrentScores()
|
||||
for (let category of scores.Categories) {
|
||||
let categoryBox = rankingsElement.appendChild(document.createElement("div"))
|
||||
categoryBox.classList.add("category")
|
||||
|
||||
categoryBox.appendChild(document.createElement("h2")).textContent = category
|
||||
|
||||
let categoryScores = []
|
||||
for (let teamID in state.TeamNames) {
|
||||
categoryScores.push({
|
||||
teamName: state.TeamNames[teamID],
|
||||
score: scores.GetPoints(category, teamID),
|
||||
})
|
||||
}
|
||||
categoryScores.sort((a, b) => b.score - a.score)
|
||||
|
||||
let table = categoryBox.appendChild(document.createElement("table"))
|
||||
let rows = 0
|
||||
for (let categoryScore of categoryScores) {
|
||||
let row = table.appendChild(document.createElement("tr"))
|
||||
row.appendChild(document.createElement("td")).textContent = categoryScore.teamName
|
||||
let td = row.appendChild(document.createElement("td"))
|
||||
td.textContent = categoryScore.score
|
||||
td.classList.add("number")
|
||||
rows += 1
|
||||
if (rows == 5) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
setInterval(update, common.Minute)
|
||||
update()
|
||||
|
|
Loading…
Reference in New Issue