Skip to content

Commit 4a157aa

Browse files
committed
[feature] Add modal that adds new game events (draft)
1 parent 6081251 commit 4a157aa

File tree

8 files changed

+276
-40
lines changed

8 files changed

+276
-40
lines changed

internal/app/controller/engine.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ func (e *Engine) processEvent(event Event) (*EventCommand, error) {
132132
return e.processCard(event.Card)
133133
} else if event.Trigger != nil {
134134
return e.processTrigger(event.Trigger)
135+
} else if event.GameEvent != nil {
136+
return e.processGameEvent(event.GameEvent)
135137
}
136138
return nil, errors.New("unknown event")
137139
}
@@ -329,6 +331,12 @@ func (e *Engine) processTrigger(t *EventTrigger) (*EventCommand, error) {
329331
return nil, nil
330332
}
331333

334+
func (e *Engine) processGameEvent(t *EventGameEvent) (*EventCommand, error) {
335+
336+
log.Printf("Processed game event %v", t)
337+
return nil, nil
338+
}
339+
332340
func revokeCard(card *EventCard, teamState *TeamInfo) error {
333341
if card.Type == CardTypeYellow {
334342
if teamState.YellowCards > 0 {

internal/app/controller/events.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,33 @@ type EventStage struct {
153153
StageOperation StageOperation `json:"stageOperation"`
154154
}
155155

156+
type EventGameEvent struct {
157+
BallLeftFieldTouchLine *EventGameEventBallLeftField `json:"ballLeftFieldTouchLine"`
158+
BallLeftFieldGoalLine *EventGameEventBallLeftField `json:"ballLeftFieldGoalLine"`
159+
}
160+
161+
type EventGameEventBallLeftField struct {
162+
Team Team `json:"team"`
163+
}
164+
165+
func (e EventGameEvent) String() string {
166+
if e.BallLeftFieldTouchLine != nil {
167+
return fmt.Sprintf("Ball left field through touch line by %v", e.BallLeftFieldTouchLine.Team)
168+
}
169+
if e.BallLeftFieldGoalLine != nil {
170+
return fmt.Sprintf("Ball left field through goal line by %v", e.BallLeftFieldGoalLine.Team)
171+
}
172+
return "unknown"
173+
}
174+
156175
// Event holds all possible events. Only one at a time can be applied
157176
type Event struct {
158-
Card *EventCard `json:"card"`
159-
Command *EventCommand `json:"command"`
160-
Modify *EventModifyValue `json:"modify"`
161-
Stage *EventStage `json:"stage"`
162-
Trigger *EventTrigger `json:"trigger"`
177+
Card *EventCard `json:"card"`
178+
Command *EventCommand `json:"command"`
179+
Modify *EventModifyValue `json:"modify"`
180+
Stage *EventStage `json:"stage"`
181+
Trigger *EventTrigger `json:"trigger"`
182+
GameEvent *EventGameEvent `json:"gameEvent"`
163183
}
164184

165185
func (e Event) String() string {
@@ -178,5 +198,8 @@ func (e Event) String() string {
178198
if e.Trigger != nil {
179199
return fmt.Sprintf("Trigger: %v", *e.Trigger)
180200
}
201+
if e.GameEvent != nil {
202+
return fmt.Sprintf("GameEvent: %v", *e.GameEvent)
203+
}
181204
return "empty event"
182205
}

src/App.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<ControlTeam class="team-views" team-color="Yellow"/>
1212
</div>
1313
<div class="main-middle-container">
14-
<GameEvents/>
14+
<Events/>
1515
<iframe src="http://localhost:8082/" frameborder="none"></iframe>
1616
</div>
1717
<div class="team-container">
@@ -30,12 +30,12 @@
3030
import ControlGeneral from "./components/control/ControlGeneral";
3131
import ControlTeam from "./components/control/ControlTeam";
3232
import ControlMatch from "./components/control/ControlMatch";
33-
import GameEvents from "./components/GameEvents";
33+
import Events from "./components/events/Events";
3434
3535
export default {
3636
name: 'app',
3737
components: {
38-
GameEvents,
38+
Events,
3939
ControlMatch,
4040
ControlTeam,
4141
ControlGeneral,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<template>
2+
<b-form-group :label="label" horizontal>
3+
<b-form-radio-group id="select-team" v-model="newEvent.team" buttons>
4+
<b-form-radio value="yellow">Yellow</b-form-radio>
5+
<b-form-radio value="blue">Blue</b-form-radio>
6+
<b-form-radio value="unknown" :disable="showUnknown">No team</b-form-radio>
7+
</b-form-radio-group>
8+
</b-form-group>
9+
</template>
10+
11+
<script>
12+
export default {
13+
name: "TeamSelection",
14+
props: {
15+
showUnknown: {
16+
type: Boolean,
17+
default: true
18+
},
19+
label: {
20+
type: String,
21+
default: ''
22+
},
23+
newEvent: {
24+
type: Object,
25+
default: function () {
26+
return {
27+
team: null
28+
}
29+
}
30+
}
31+
},
32+
}
33+
</script>
34+
35+
<style scoped>
36+
</style>

src/components/GameEvents.vue renamed to src/components/events/EventTable.vue

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
11
<template>
2-
<div>
3-
<b-table striped hover small
4-
responsive="true"
5-
:sort-by.sync="sortBy"
6-
:sort-desc.sync="sortDesc"
7-
:per-page="perPage"
8-
:current-page="currentPage"
9-
:items="gameEvents"
10-
:fields="fields">
11-
<template slot="timestamp" slot-scope="data">
12-
{{formatTimestamp(data.item.timestamp)}}
13-
</template>
14-
<template slot="stageTime" slot-scope="data">
15-
<span v-format-ns-duration="data.item.stageTime"></span>
16-
</template>
17-
</b-table>
18-
<b-pagination size="sm"
19-
align="center"
20-
:total-rows="gameEvents.length"
21-
v-model="currentPage"
22-
:per-page="perPage">
23-
</b-pagination>
24-
</div>
2+
<b-table striped hover small
3+
responsive="true"
4+
:sort-by.sync="sortBy"
5+
:sort-desc.sync="sortDesc"
6+
:per-page="perPage"
7+
:current-page="currentPage"
8+
:items="events"
9+
:fields="fields">
10+
<template slot="timestamp" slot-scope="data">
11+
{{formatTimestamp(data.item.timestamp)}}
12+
</template>
13+
<template slot="stageTime" slot-scope="data">
14+
<span v-format-ns-duration="data.item.stageTime"></span>
15+
</template>
16+
</b-table>
2517
</template>
2618

2719
<script>
28-
import "../date.format";
20+
import "../../date.format";
2921
3022
export default {
31-
name: "GameEvents",
23+
name: "EventTable",
24+
props: {
25+
currentPage: {
26+
type: Number,
27+
default: 1
28+
},
29+
perPage: {
30+
type: Number,
31+
default: 5
32+
},
33+
events: {
34+
type: Array
35+
}
36+
},
3237
data() {
3338
return {
3439
sortBy: 'timestamp',
3540
sortDesc: true,
36-
currentPage: 1,
37-
perPage: 5,
3841
fields: [
3942
{
4043
key: 'timestamp',
@@ -63,11 +66,6 @@
6366
],
6467
}
6568
},
66-
computed: {
67-
gameEvents() {
68-
return this.$store.state.gameEvents;
69-
}
70-
},
7169
methods: {
7270
formatTimestamp(timestamp) {
7371
let date = new Date(timestamp);

src/components/events/Events.vue

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<div>
3+
<EventTable :current-page="currentPage" :per-page="perPage" :events="events"/>
4+
<div class="event-controls-container">
5+
<b-pagination size="sm"
6+
:total-rows="events.length"
7+
v-model="currentPage"
8+
:per-page="perPage">
9+
</b-pagination>
10+
11+
<b-btn v-b-modal.new-event-modal size="sm" variant="primary">New</b-btn>
12+
<b-modal id="new-event-modal"
13+
title="New Game Event"
14+
:lazy="true">
15+
<NewEvent/>
16+
<div slot="modal-footer">
17+
<!-- hide modal buttons -->
18+
</div>
19+
</b-modal>
20+
</div>
21+
</div>
22+
</template>
23+
24+
<script>
25+
import EventTable from "./EventTable";
26+
import NewEvent from "./NewEvent";
27+
28+
export default {
29+
name: "Events",
30+
components: {EventTable, NewEvent},
31+
data() {
32+
return {
33+
currentPage: 1,
34+
perPage: 5,
35+
}
36+
},
37+
computed: {
38+
events() {
39+
return this.$store.state.gameEvents;
40+
}
41+
},
42+
}
43+
</script>
44+
45+
<style scoped>
46+
.event-controls-container {
47+
display: flex;
48+
flex-flow: row wrap;
49+
justify-content: center;
50+
}
51+
52+
.event-controls-container button {
53+
margin-bottom: 1rem;
54+
margin-left: 1rem;
55+
}
56+
</style>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<template>
2+
<div>
3+
<b-card no-body class="mb-1">
4+
<b-card-header header-tag="header" class="p-1" role="tab">
5+
<b-btn block href="#" v-b-toggle.accordion-event1 variant="secondary">
6+
through the touch line
7+
</b-btn>
8+
</b-card-header>
9+
<b-collapse id="accordion-event1" accordion="accordion-event" role="tabpanel">
10+
<b-card-body>
11+
<TeamSelection :newEvent="newEvent" label="By: "/>
12+
<b-button variant="primary"
13+
@click="send('ballLeftFieldTouchLine')"
14+
:disabled="newEvent.team === null">
15+
Add
16+
</b-button>
17+
</b-card-body>
18+
</b-collapse>
19+
</b-card>
20+
<b-card no-body class="mb-1">
21+
<b-card-header header-tag="header" class="p-1" role="tab">
22+
<b-btn block href="#" v-b-toggle.accordion-event2 variant="secondary">
23+
through the goal line
24+
</b-btn>
25+
</b-card-header>
26+
<b-collapse id="accordion-event2" accordion="accordion-event" role="tabpanel">
27+
<b-card-body>
28+
<TeamSelection :newEvent="newEvent" label="By: "/>
29+
<b-button variant="primary"
30+
@click="send('ballLeftFieldGoalLine')"
31+
:disabled="newEvent.team === null">
32+
Add
33+
</b-button>
34+
</b-card-body>
35+
</b-collapse>
36+
</b-card>
37+
</div>
38+
</template>
39+
40+
<script>
41+
import TeamSelection from "../common/TeamSelection";
42+
43+
export default {
44+
name: "NewBallOutOfFieldEvent",
45+
components: {TeamSelection},
46+
data() {
47+
return {
48+
newEvent: {
49+
team: null
50+
}
51+
}
52+
},
53+
methods: {
54+
send: function (type) {
55+
this.$socket.sendObj({gameEvent: {[type]: this.newEvent}});
56+
this.$root.$emit('bv::hide::modal', 'new-event-modal');
57+
}
58+
},
59+
}
60+
</script>
61+
62+
<style scoped>
63+
64+
</style>

src/components/events/NewEvent.vue

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<template>
2+
<div>
3+
<b-card no-body class="mb-1">
4+
<b-card-header header-tag="header" class="p-1" role="tab">
5+
<b-btn block href="#" v-b-toggle.accordion-event-category1 variant="primary">Ball left field</b-btn>
6+
</b-card-header>
7+
<b-collapse id="accordion-event-category1" accordion="accordion-event-category" role="tabpanel">
8+
<b-card-body>
9+
<NewBallOutOfFieldEvent/>
10+
</b-card-body>
11+
</b-collapse>
12+
</b-card>
13+
<b-card no-body class="mb-1">
14+
<b-card-header header-tag="header" class="p-1" role="tab">
15+
<b-btn block href="#" v-b-toggle.accordion-event-category2 variant="primary">Minor offence</b-btn>
16+
</b-card-header>
17+
<b-collapse id="accordion-event-category2" accordion="accordion-event-category" role="tabpanel">
18+
<b-card-body>
19+
<p class="card-text">
20+
A minor offence
21+
</p>
22+
</b-card-body>
23+
</b-collapse>
24+
</b-card>
25+
<b-card no-body class="mb-1">
26+
<b-card-header header-tag="header" class="p-1" role="tab">
27+
<b-btn block href="#" v-b-toggle.accordion-event-category3 variant="primary">Foul</b-btn>
28+
</b-card-header>
29+
<b-collapse id="accordion-event-category3" accordion="accordion-event-category" role="tabpanel">
30+
<b-card-body>
31+
<p class="card-text">
32+
A foul
33+
</p>
34+
</b-card-body>
35+
</b-collapse>
36+
</b-card>
37+
</div>
38+
</template>
39+
40+
<script>
41+
import NewBallOutOfFieldEvent from "./NewBallOutOfFieldEvent";
42+
43+
export default {
44+
name: "NewEvent",
45+
components: {NewBallOutOfFieldEvent},
46+
}
47+
</script>
48+
49+
<style scoped>
50+
51+
</style>

0 commit comments

Comments
 (0)