Skip to content

Commit 377001d

Browse files
committed
[feature] Show event proposals in UI
1 parent 9431c4d commit 377001d

File tree

6 files changed

+98
-11
lines changed

6 files changed

+98
-11
lines changed

internal/app/controller/state.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ const (
257257

258258
// GameEventProposal holds a proposal for a game event from an autoRef
259259
type GameEventProposal struct {
260-
ProposerId string
261-
GameEvent GameEvent
262-
ValidUntil time.Time
260+
ProposerId string `json:"proposerId"`
261+
GameEvent GameEvent `json:"gameEvent"`
262+
ValidUntil time.Time `json:"validUntil"`
263263
}
264264

265265
// State of the game

src/App.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<div class="team-container">
2727
<TeamOverview class="team-views" team-color="Blue"/>
2828
<ControlTeam class="team-views" team-color="Blue"/>
29+
<EventProposals class="team-views event-proposals"/>
2930
</div>
3031
</div>
3132
<ControlMatch id="match-controls"/>
@@ -39,10 +40,12 @@
3940
import ControlTeam from "./components/control/ControlTeam";
4041
import ControlMatch from "./components/control/ControlMatch";
4142
import Events from "./components/events/Events";
43+
import EventProposals from "./components/events/EventProposals";
4244
4345
export default {
4446
name: 'app',
4547
components: {
48+
EventProposals,
4649
Events,
4750
ControlMatch,
4851
ControlTeam,
@@ -149,6 +152,7 @@
149152
.team-container {
150153
display: flex;
151154
flex-direction: column;
155+
align-items: stretch;
152156
}
153157
154158
#match-controls {
@@ -168,4 +172,12 @@
168172
width: 100%;
169173
height: 100%
170174
}
175+
176+
.team-yellow {
177+
color: gold;
178+
}
179+
180+
.team-blue {
181+
color: blue;
182+
}
171183
</style>

src/components/GameState.vue

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,4 @@
5555
</script>
5656

5757
<style scoped>
58-
.team-yellow {
59-
color: gold;
60-
}
61-
62-
.team-blue {
63-
color: blue;
64-
}
6558
</style>

src/components/events/EventBehavior.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div>
33
<table>
4-
<tr v-for="eventType in eventTypes">
4+
<tr v-for="eventType in eventTypes" :key="eventType">
55
<td align="left">{{eventType}}</td>
66
<td>
77
<div class="btn-group-toggle btn-group">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<template>
2+
<div>
3+
<h2>Proposed Game Events</h2>
4+
<div class="content">
5+
<span v-if="!eventProposalsPresent">None</span>
6+
<div v-if="eventProposalsPresent" v-for="(proposal, index) in eventProposals"
7+
:key="index">
8+
<span :class="{'team-blue': byTeam(proposal) === 2, 'team-yellow': byTeam(proposal) === 1}">
9+
{{proposal.gameEvent.type}}
10+
</span>
11+
<span>by {{proposal.proposerId}}</span>
12+
(<span v-format-ns-duration="proposalTimeout(proposal.validUntil)"></span>):
13+
<p>
14+
<span v-for="detail in detailsList(proposal)"
15+
:key="detail.key">{{detail.key}}: {{detail.value}}<br/></span>
16+
</p>
17+
</div>
18+
</div>
19+
</div>
20+
</template>
21+
22+
<script>
23+
export default {
24+
name: "EventProposals",
25+
computed: {
26+
state() {
27+
return this.$store.state.refBoxState
28+
},
29+
eventProposals() {
30+
return this.state.gameEventProposals;
31+
},
32+
eventProposalsPresent() {
33+
return this.eventProposals != null && this.eventProposals.length > 0;
34+
}
35+
},
36+
methods: {
37+
details(proposal) {
38+
let key = Object.keys(proposal.gameEvent.details)[0];
39+
return proposal.gameEvent.details[key];
40+
},
41+
detailsStr(proposal) {
42+
let p = this.details(proposal);
43+
delete p.by_team;
44+
return p;
45+
},
46+
detailsList(proposal) {
47+
let list = [];
48+
let details = this.details(proposal);
49+
delete details.by_team;
50+
Object.keys(details).forEach(function (key, i) {
51+
list[i] = {key: key, value: details[key]}
52+
});
53+
return list;
54+
},
55+
byTeam(proposal) {
56+
let details = this.details(proposal);
57+
if (details.hasOwnProperty('by_team')) {
58+
return details.by_team;
59+
}
60+
return '';
61+
},
62+
proposalTimeout(v) {
63+
let validUntil = new Date(v);
64+
let now = Date.now();
65+
let remaining = validUntil - now;
66+
if (remaining < 0) {
67+
return 0;
68+
}
69+
return remaining * 1e6;
70+
},
71+
}
72+
}
73+
</script>
74+
75+
<style scoped>
76+
.content {
77+
text-align: left;
78+
overflow-y: auto;
79+
max-height: 15em;
80+
}
81+
</style>

src/store.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export class RefBoxState {
3535
nextCommandFor = '';
3636
autoRefsConnected = [];
3737
gameEventBehavior = {};
38+
gameEventProposals = [{proposerId: '', gameEvent: {type: '', details: {foo: 'bar'}}, validUntil: 0}];
3839
}
3940

4041
export default new Vuex.Store({

0 commit comments

Comments
 (0)