mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Refined announcer display.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,3 +24,4 @@ _testmain.go
|
|||||||
*.test
|
*.test
|
||||||
*.db
|
*.db
|
||||||
*.out
|
*.out
|
||||||
|
.DS_Store
|
||||||
|
|||||||
109
displays.go
109
displays.go
@@ -217,40 +217,9 @@ func AnnouncerDisplayHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
handleWebErr(w, err)
|
handleWebErr(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble info about the current match.
|
|
||||||
matchType := mainArena.currentMatch.CapitalizedType()
|
|
||||||
red1 := mainArena.AllianceStations["R1"].team
|
|
||||||
red2 := mainArena.AllianceStations["R2"].team
|
|
||||||
red3 := mainArena.AllianceStations["R3"].team
|
|
||||||
blue1 := mainArena.AllianceStations["B1"].team
|
|
||||||
blue2 := mainArena.AllianceStations["B2"].team
|
|
||||||
blue3 := mainArena.AllianceStations["B3"].team
|
|
||||||
|
|
||||||
// Assemble info about the saved match result.
|
|
||||||
var redScoreSummary, blueScoreSummary *ScoreSummary
|
|
||||||
var savedMatchType, savedMatchDisplayName string
|
|
||||||
savedMatchType = mainArena.savedMatch.CapitalizedType()
|
|
||||||
savedMatchDisplayName = mainArena.savedMatch.DisplayName
|
|
||||||
redScoreSummary = mainArena.savedMatchResult.RedScoreSummary()
|
|
||||||
blueScoreSummary = mainArena.savedMatchResult.BlueScoreSummary()
|
|
||||||
data := struct {
|
data := struct {
|
||||||
*EventSettings
|
*EventSettings
|
||||||
MatchType string
|
}{eventSettings}
|
||||||
MatchDisplayName string
|
|
||||||
Red1 *Team
|
|
||||||
Red2 *Team
|
|
||||||
Red3 *Team
|
|
||||||
Blue1 *Team
|
|
||||||
Blue2 *Team
|
|
||||||
Blue3 *Team
|
|
||||||
SavedMatchResult *MatchResult
|
|
||||||
SavedMatchType string
|
|
||||||
SavedMatchDisplayName string
|
|
||||||
RedScoreSummary *ScoreSummary
|
|
||||||
BlueScoreSummary *ScoreSummary
|
|
||||||
}{eventSettings, matchType, mainArena.currentMatch.DisplayName, red1, red2, red3, blue1, blue2, blue3,
|
|
||||||
mainArena.savedMatchResult, savedMatchType, savedMatchDisplayName, redScoreSummary, blueScoreSummary}
|
|
||||||
err = template.ExecuteTemplate(w, "base", data)
|
err = template.ExecuteTemplate(w, "base", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleWebErr(w, err)
|
handleWebErr(w, err)
|
||||||
@@ -271,10 +240,33 @@ func AnnouncerDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer close(matchLoadTeamsListener)
|
defer close(matchLoadTeamsListener)
|
||||||
matchTimeListener := mainArena.matchTimeNotifier.Listen()
|
matchTimeListener := mainArena.matchTimeNotifier.Listen()
|
||||||
defer close(matchTimeListener)
|
defer close(matchTimeListener)
|
||||||
|
realtimeScoreListener := mainArena.realtimeScoreNotifier.Listen()
|
||||||
|
defer close(realtimeScoreListener)
|
||||||
scorePostedListener := mainArena.scorePostedNotifier.Listen()
|
scorePostedListener := mainArena.scorePostedNotifier.Listen()
|
||||||
defer close(scorePostedListener)
|
defer close(scorePostedListener)
|
||||||
|
audienceDisplayListener := mainArena.audienceDisplayNotifier.Listen()
|
||||||
|
defer close(audienceDisplayListener)
|
||||||
|
|
||||||
// Send the various notifications immediately upon connection.
|
// Send the various notifications immediately upon connection.
|
||||||
|
var data interface{}
|
||||||
|
data = struct {
|
||||||
|
MatchType string
|
||||||
|
MatchDisplayName string
|
||||||
|
Red1 *Team
|
||||||
|
Red2 *Team
|
||||||
|
Red3 *Team
|
||||||
|
Blue1 *Team
|
||||||
|
Blue2 *Team
|
||||||
|
Blue3 *Team
|
||||||
|
}{mainArena.currentMatch.CapitalizedType(), mainArena.currentMatch.DisplayName,
|
||||||
|
mainArena.AllianceStations["R1"].team, mainArena.AllianceStations["R2"].team,
|
||||||
|
mainArena.AllianceStations["R3"].team, mainArena.AllianceStations["B1"].team,
|
||||||
|
mainArena.AllianceStations["B2"].team, mainArena.AllianceStations["B3"].team}
|
||||||
|
err = websocket.Write("setMatch", data)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Websocket error: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
err = websocket.Write("matchTiming", mainArena.matchTiming)
|
err = websocket.Write("matchTiming", mainArena.matchTiming)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Websocket error: %s", err)
|
log.Printf("Websocket error: %s", err)
|
||||||
@@ -285,6 +277,15 @@ func AnnouncerDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("Websocket error: %s", err)
|
log.Printf("Websocket error: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data = struct {
|
||||||
|
RedScore int
|
||||||
|
BlueScore int
|
||||||
|
}{mainArena.redRealtimeScore.Score(), mainArena.blueRealtimeScore.Score()}
|
||||||
|
err = websocket.Write("realtimeScore", data)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Websocket error: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Spin off a goroutine to listen for notifications and pass them on through the websocket.
|
// Spin off a goroutine to listen for notifications and pass them on through the websocket.
|
||||||
go func() {
|
go func() {
|
||||||
@@ -296,20 +297,56 @@ func AnnouncerDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageType = "reload"
|
messageType = "setMatch"
|
||||||
message = nil
|
message = struct {
|
||||||
|
MatchType string
|
||||||
|
MatchDisplayName string
|
||||||
|
Red1 *Team
|
||||||
|
Red2 *Team
|
||||||
|
Red3 *Team
|
||||||
|
Blue1 *Team
|
||||||
|
Blue2 *Team
|
||||||
|
Blue3 *Team
|
||||||
|
}{mainArena.currentMatch.CapitalizedType(), mainArena.currentMatch.DisplayName,
|
||||||
|
mainArena.AllianceStations["R1"].team, mainArena.AllianceStations["R2"].team,
|
||||||
|
mainArena.AllianceStations["R3"].team, mainArena.AllianceStations["B1"].team,
|
||||||
|
mainArena.AllianceStations["B2"].team, mainArena.AllianceStations["B3"].team}
|
||||||
case matchTimeSec, ok := <-matchTimeListener:
|
case matchTimeSec, ok := <-matchTimeListener:
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageType = "matchTime"
|
messageType = "matchTime"
|
||||||
message = MatchTimeMessage{mainArena.MatchState, matchTimeSec.(int)}
|
message = MatchTimeMessage{mainArena.MatchState, matchTimeSec.(int)}
|
||||||
|
case _, ok := <-realtimeScoreListener:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messageType = "realtimeScore"
|
||||||
|
message = struct {
|
||||||
|
RedScore int
|
||||||
|
BlueScore int
|
||||||
|
}{mainArena.redRealtimeScore.Score(), mainArena.blueRealtimeScore.Score()}
|
||||||
case _, ok := <-scorePostedListener:
|
case _, ok := <-scorePostedListener:
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageType = "reload"
|
messageType = "setFinalScore"
|
||||||
message = nil
|
message = struct {
|
||||||
|
MatchType string
|
||||||
|
MatchDisplayName string
|
||||||
|
RedScoreSummary *ScoreSummary
|
||||||
|
BlueScoreSummary *ScoreSummary
|
||||||
|
RedFouls []Foul
|
||||||
|
BlueFouls []Foul
|
||||||
|
}{mainArena.savedMatch.CapitalizedType(), mainArena.savedMatch.DisplayName,
|
||||||
|
mainArena.savedMatchResult.RedScoreSummary(), mainArena.savedMatchResult.BlueScoreSummary(),
|
||||||
|
mainArena.savedMatchResult.RedFouls, mainArena.savedMatchResult.BlueFouls}
|
||||||
|
case _, ok := <-audienceDisplayListener:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messageType = "setAudienceDisplay"
|
||||||
|
message = mainArena.audienceDisplayScreen
|
||||||
}
|
}
|
||||||
err = websocket.Write(messageType, message)
|
err = websocket.Write(messageType, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -123,11 +123,13 @@ func TestAnnouncerDisplayWebsocket(t *testing.T) {
|
|||||||
ws := &Websocket{conn}
|
ws := &Websocket{conn}
|
||||||
|
|
||||||
// Should get a few status updates right after connection.
|
// Should get a few status updates right after connection.
|
||||||
|
readWebsocketType(t, ws, "setMatch")
|
||||||
readWebsocketType(t, ws, "matchTiming")
|
readWebsocketType(t, ws, "matchTiming")
|
||||||
readWebsocketType(t, ws, "matchTime")
|
readWebsocketType(t, ws, "matchTime")
|
||||||
|
readWebsocketType(t, ws, "realtimeScore")
|
||||||
|
|
||||||
mainArena.matchLoadTeamsNotifier.Notify(nil)
|
mainArena.matchLoadTeamsNotifier.Notify(nil)
|
||||||
readWebsocketType(t, ws, "reload")
|
readWebsocketType(t, ws, "setMatch")
|
||||||
mainArena.AllianceStations["R1"].Bypass = true
|
mainArena.AllianceStations["R1"].Bypass = true
|
||||||
mainArena.AllianceStations["R2"].Bypass = true
|
mainArena.AllianceStations["R2"].Bypass = true
|
||||||
mainArena.AllianceStations["R3"].Bypass = true
|
mainArena.AllianceStations["R3"].Bypass = true
|
||||||
@@ -136,9 +138,15 @@ func TestAnnouncerDisplayWebsocket(t *testing.T) {
|
|||||||
mainArena.AllianceStations["B3"].Bypass = true
|
mainArena.AllianceStations["B3"].Bypass = true
|
||||||
mainArena.StartMatch()
|
mainArena.StartMatch()
|
||||||
mainArena.Update()
|
mainArena.Update()
|
||||||
readWebsocketType(t, ws, "matchTime")
|
messages := readWebsocketMultiple(t, ws, 2)
|
||||||
|
_, ok := messages["setAudienceDisplay"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
_, ok = messages["matchTime"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
mainArena.realtimeScoreNotifier.Notify(nil)
|
||||||
|
readWebsocketType(t, ws, "realtimeScore")
|
||||||
mainArena.scorePostedNotifier.Notify(nil)
|
mainArena.scorePostedNotifier.Notify(nil)
|
||||||
readWebsocketType(t, ws, "reload")
|
readWebsocketType(t, ws, "setFinalScore")
|
||||||
|
|
||||||
// Test triggering the final score screen.
|
// Test triggering the final score screen.
|
||||||
ws.Write("setAudienceDisplay", "score")
|
ws.Write("setAudienceDisplay", "score")
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
.modal-large {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
.ds-status, .robot-status, .battery-status, .bypass-status {
|
.ds-status, .robot-status, .battery-status, .bypass-status {
|
||||||
background-color: #aaa;
|
background-color: #aaa;
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|||||||
@@ -4,20 +4,47 @@
|
|||||||
// Client-side logic for the announcer display.
|
// Client-side logic for the announcer display.
|
||||||
|
|
||||||
var websocket;
|
var websocket;
|
||||||
var blinkTimeout;
|
var teamTemplate = Handlebars.compile($("#teamTemplate").html());
|
||||||
|
var matchResultTemplate = Handlebars.compile($("#matchResultTemplate").html());
|
||||||
|
|
||||||
|
var handleSetAudienceDisplay = function(targetScreen) {
|
||||||
|
// Hide the final results so that they aren't blocking the current teams when the announcer needs them most.
|
||||||
|
if (targetScreen == "intro" || targetScreen == "match") {
|
||||||
|
$("#matchResult").modal("hide");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleSetMatch = function(data) {
|
||||||
|
$("#matchName").text(data.MatchType + " Match " + data.MatchDisplayName);
|
||||||
|
$("#red1").html(teamTemplate(data.Red1));
|
||||||
|
$("#red2").html(teamTemplate(data.Red2));
|
||||||
|
$("#red3").html(teamTemplate(data.Red3));
|
||||||
|
$("#blue1").html(teamTemplate(data.Blue1));
|
||||||
|
$("#blue2").html(teamTemplate(data.Blue2));
|
||||||
|
$("#blue3").html(teamTemplate(data.Blue3));
|
||||||
|
};
|
||||||
|
|
||||||
var handleMatchTime = function(data) {
|
var handleMatchTime = function(data) {
|
||||||
translateMatchTime(data, function(matchState, matchStateText, countdownSec) {
|
translateMatchTime(data, function(matchState, matchStateText, countdownSec) {
|
||||||
$("#matchState").text(matchStateText);
|
$("#matchState").text(matchStateText);
|
||||||
$("#matchTime").text(getCountdown(data.MatchState, data.MatchTimeSec));
|
$("#matchTime").text(getCountdown(data.MatchState, data.MatchTimeSec));
|
||||||
if (matchState == "PRE_MATCH" || matchState == "POST_MATCH") {
|
|
||||||
$("#savedMatchResult").show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var handleRealtimeScore = function(data) {
|
||||||
|
$("#redScore").text(data.RedScore);
|
||||||
|
$("#blueScore").text(data.BlueScore);
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleSetFinalScore = function(data) {
|
||||||
|
console.log(data);
|
||||||
|
$("#scoreMatchName").text(data.MatchType + " Match " + data.MatchDisplayName);
|
||||||
|
$("#redScoreDetails").html(matchResultTemplate({score: data.RedScoreSummary, fouls: data.RedFouls}));
|
||||||
|
$("#blueScoreDetails").html(matchResultTemplate({score: data.BlueScoreSummary, fouls: data.BlueFouls}));
|
||||||
|
$("#matchResult").modal("show");
|
||||||
|
};
|
||||||
|
|
||||||
var postMatchResult = function(data) {
|
var postMatchResult = function(data) {
|
||||||
clearTimeout(blinkTimeout);
|
|
||||||
$("#savedMatchResult").attr("data-blink", false);
|
$("#savedMatchResult").attr("data-blink", false);
|
||||||
websocket.send("setAudienceDisplay", "score");
|
websocket.send("setAudienceDisplay", "score");
|
||||||
}
|
}
|
||||||
@@ -25,12 +52,16 @@ var postMatchResult = function(data) {
|
|||||||
$(function() {
|
$(function() {
|
||||||
// Set up the websocket back to the server.
|
// Set up the websocket back to the server.
|
||||||
websocket = new CheesyWebsocket("/displays/announcer/websocket", {
|
websocket = new CheesyWebsocket("/displays/announcer/websocket", {
|
||||||
|
setMatch: function(event) { handleSetMatch(event.data); },
|
||||||
matchTiming: function(event) { handleMatchTiming(event.data); },
|
matchTiming: function(event) { handleMatchTiming(event.data); },
|
||||||
matchTime: function(event) { handleMatchTime(event.data); }
|
matchTime: function(event) { handleMatchTime(event.data); },
|
||||||
|
realtimeScore: function(event) { handleRealtimeScore(event.data); },
|
||||||
|
setFinalScore: function(event) { handleSetFinalScore(event.data); },
|
||||||
|
setAudienceDisplay: function(event) { handleSetAudienceDisplay(event.data); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make the score blink.
|
// Make the score blink.
|
||||||
blinkTimeout = setInterval(function() {
|
setInterval(function() {
|
||||||
var blinkOn = $("#savedMatchResult").attr("data-blink") == "true";
|
var blinkOn = $("#savedMatchResult").attr("data-blink") == "true";
|
||||||
$("#savedMatchResult").attr("data-blink", !blinkOn);
|
$("#savedMatchResult").attr("data-blink", !blinkOn);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{{define "title"}}Announcer Display{{end}}
|
{{define "title"}}Announcer Display{{end}}
|
||||||
{{define "body"}}
|
{{define "body"}}
|
||||||
<h3>{{.MatchType}} Match {{.MatchDisplayName}}</h3>
|
<h3 id="matchName"></h3>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -12,14 +12,14 @@
|
|||||||
<th class="nowrap">Rookie Year</th>
|
<th class="nowrap">Rookie Year</th>
|
||||||
<th class="nowrap">Recent Accomplishments</th>
|
<th class="nowrap">Recent Accomplishments</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="well-darkred">{{template "announcerDisplayTeam" .Red1}}</tr>
|
|
||||||
<tr class="well-darkred">{{template "announcerDisplayTeam" .Red2}}</tr>
|
|
||||||
<tr class="well-darkred">{{template "announcerDisplayTeam" .Red3}}</tr>
|
|
||||||
<tr class="well-darkblue">{{template "announcerDisplayTeam" .Blue1}}</tr>
|
|
||||||
<tr class="well-darkblue">{{template "announcerDisplayTeam" .Blue2}}</tr>
|
|
||||||
<tr class="well-darkblue">{{template "announcerDisplayTeam" .Blue3}}</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<tr class="well-darkred" id="red1"></tr>
|
||||||
|
<tr class="well-darkred" id="red2"></tr>
|
||||||
|
<tr class="well-darkred" id="red3"></tr>
|
||||||
|
<tr class="well-darkblue" id="blue1"></tr>
|
||||||
|
<tr class="well-darkblue" id="blue2"></tr>
|
||||||
|
<tr class="well-darkblue" id="blue3"></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -30,80 +30,86 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
</div>
|
</div>
|
||||||
{{if .SavedMatchResult}}
|
<div id="matchResult" class="modal" style="top: 10%;">
|
||||||
<div class="col-lg-8 col-lg-offset-2 well well-sm" id="savedMatchResult" style="display: none;" data-blink="off">
|
<div class="modal-dialog modal-large">
|
||||||
<div class="col-lg-8">
|
<div class="modal-content">
|
||||||
<h3>Final Results – {{.SavedMatchType}} Match {{.SavedMatchDisplayName}}</h3>
|
<div class="modal-header" id="savedMatchResult">
|
||||||
</div>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<div class="col-lg-6">
|
<h4 class="modal-title">Final Results – <span id="scoreMatchName"></span></h4>
|
||||||
<div class="well well-darkred">
|
</div>
|
||||||
{{template "announcerDisplayResult" dict "fouls" .SavedMatchResult.RedFouls "summary" .RedScoreSummary}}
|
<div class="modal-body row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="well well-darkred" id="redScoreDetails"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="well well-darkblue" id="blueScoreDetails"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<form class="form-horizontal" action="/setup/teams/clear" method="POST">
|
||||||
|
<button type="button" class="btn btn-info" onclick="postMatchResult();">
|
||||||
|
Post Score to Audience Display
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Dismiss</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
|
||||||
<div class="well well-darkblue">
|
|
||||||
{{template "announcerDisplayResult" dict "fouls" .SavedMatchResult.BlueFouls "summary" .BlueScoreSummary}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center col-lg-12">
|
|
||||||
<button type="button" class="btn btn-info" onclick="postMatchResult();">Post Score to Audience Display</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
<script id="teamTemplate" type="text/x-handlebars-template">
|
||||||
|
{{"{{#if this}}"}}
|
||||||
|
<td><b>{{"{{Id}}"}}</b></td>
|
||||||
|
<td class="nowrap">{{"{{Nickname}}"}}</td>
|
||||||
|
<td class="nowrap">{{"{{City}}"}}, {{"{{StateProv}}"}}, {{"{{Country}}"}}</td>
|
||||||
|
<td>{{"{{Name}}"}}</td>
|
||||||
|
<td class="nowrap">{{"{{RobotName}}"}}</td>
|
||||||
|
<td>{{"{{RookieYear}}"}}</td>
|
||||||
|
<td class="nowrap">2014 Central Valley Regional - Gracious Professionalism<br />Placeholder</td>
|
||||||
|
{{"{{else}}"}}
|
||||||
|
<td colspan="100">No team present</td>
|
||||||
|
{{"{{/if}}"}}
|
||||||
|
</script>
|
||||||
|
<script id="matchResultTemplate" type="text/x-handlebars-template">
|
||||||
|
<h4>Score</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-7 col-lg-offset-1 control-label">Auto Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.AutoPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-7 col-lg-offset-1 control-label">Teleop Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.TeleopPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 col-lg-offset-2 control-label">Assist Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.AssistPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 col-lg-offset-2 control-label">Truss/Catch Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.TrussCatchPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 col-lg-offset-2 control-label">Goal Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.GoalPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-7 col-lg-offset-1 control-label">Foul Points</div>
|
||||||
|
<div class="col-lg-2">{{"{{score.FoulPoints}}"}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-7 col-lg-offset-1 control-label"><b>Final Score</b></div>
|
||||||
|
<div class="col-lg-2"><b>{{"{{score.Score}}"}}</b></div>
|
||||||
|
</div>
|
||||||
|
<h4>Fouls</h4>
|
||||||
|
{{"{{#each fouls}}"}}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4 col-lg-offset-1">{{"{{#if IsTechnical}}"}}Tech {{"{{/if}}"}}Foul</div>
|
||||||
|
<div class="col-lg-3">{{"{{TeamId}}"}}</div>
|
||||||
|
<div class="col-lg-3">{{"{{Rule}}"}}</div>
|
||||||
|
</div>
|
||||||
|
{{"{{/each}}"}}
|
||||||
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "script"}}
|
{{define "script"}}
|
||||||
<script src="/static/js/match_timing.js"></script>
|
<script src="/static/js/match_timing.js"></script>
|
||||||
<script src="/static/js/announcer_display.js"></script>
|
<script src="/static/js/announcer_display.js"></script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "announcerDisplayTeam"}}
|
|
||||||
{{if .}}
|
|
||||||
<td><b>{{.Id}}</b></td>
|
|
||||||
<td class="nowrap">{{.Nickname}}</td>
|
|
||||||
<td class="nowrap">{{.City}}, {{.StateProv}}, {{.Country}}</td>
|
|
||||||
<td>{{.Name}}</td>
|
|
||||||
<td class="nowrap">{{.RobotName}}</td>
|
|
||||||
<td>{{.RookieYear}}</td>
|
|
||||||
<td class="nowrap">2014 Central Valley Regional - Gracious Professionalism<br />Placeholder</td>
|
|
||||||
{{else}}
|
|
||||||
<td colspan="100">No team present</td>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
{{define "announcerDisplayResult"}}
|
|
||||||
<h4>Score</h4>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-7 col-lg-offset-1 control-label">Auto Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.AutoPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-7 col-lg-offset-1 control-label">Teleop Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.TeleopPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-lg-offset-2 control-label">Assist Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.AssistPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-lg-offset-2 control-label">Truss/Catch Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.TrussCatchPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-6 col-lg-offset-2 control-label">Goal Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.GoalPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-7 col-lg-offset-1 control-label">Foul Points</div>
|
|
||||||
<div class="col-lg-2">{{.summary.FoulPoints}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-7 col-lg-offset-1 control-label"><b>Final Score</b></div>
|
|
||||||
<div class="col-lg-2"><b>{{.summary.Score}}</b></div>
|
|
||||||
</div>
|
|
||||||
<h4>Fouls</h4>
|
|
||||||
{{range $foul := .fouls}}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4 col-lg-offset-1">{{if $foul.IsTechnical}}Tech {{end}}Foul</div>
|
|
||||||
<div class="col-lg-3">{{$foul.TeamId}}</div>
|
|
||||||
<div class="col-lg-3">{{$foul.Rule}}</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
|
|||||||
@@ -103,7 +103,6 @@
|
|||||||
<audio id="match-abort" src="/static/audio/match_abort.mp3" type="audio/mp3" preload="auto" />
|
<audio id="match-abort" src="/static/audio/match_abort.mp3" type="audio/mp3" preload="auto" />
|
||||||
<audio id="match-resume" src="/static/audio/match_resume.wav" type="audio/wav" preload="auto" />
|
<audio id="match-resume" src="/static/audio/match_resume.wav" type="audio/wav" preload="auto" />
|
||||||
<audio id="match-endgame" src="/static/audio/match_endgame.wav" type="audio/wav" preload="auto" />
|
<audio id="match-endgame" src="/static/audio/match_endgame.wav" type="audio/wav" preload="auto" />
|
||||||
<script src="/static/js/lib/handlebars-1.3.0.js"></script>
|
|
||||||
<script src="/static/js/lib/jquery.min.js"></script>
|
<script src="/static/js/lib/jquery.min.js"></script>
|
||||||
<script src="/static/js/lib/jquery.json-2.4.min.js"></script>
|
<script src="/static/js/lib/jquery.json-2.4.min.js"></script>
|
||||||
<script src="/static/js/lib/jquery.websocket-0.0.1.js"></script>
|
<script src="/static/js/lib/jquery.websocket-0.0.1.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user