Skip to content

Commit d1f0a3e

Browse files
committed
improved rendering of turns and phases in the log
1 parent 52be2c3 commit d1f0a3e

3 files changed

Lines changed: 208 additions & 79 deletions

File tree

src/client/log/log.css

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,35 @@
66
* https://opensource.org/licenses/MIT.
77
*/
88

9+
.gamelog {
10+
display: grid;
11+
grid-template-columns: 30px 1fr 30px;
12+
:grid-auto-rows: auto;
13+
grid-auto-flow: column;
14+
}
15+
16+
.gamelog .turn-marker {
17+
display: flex;
18+
justify-content: center;
19+
align-items: center;
20+
grid-column: 1;
21+
background: #555;
22+
color: #eee;
23+
text-align: center;
24+
font-weight: bold;
25+
border: 1px solid #888;
26+
}
27+
928
.gamelog .log-event {
29+
grid-column: 2;
1030
cursor: pointer;
31+
overflow: hidden;
1132
display: flex;
1233
flex-direction: column;
1334
justify-content: space-between;
1435
background: #fff;
1536
border: 1px dotted #ccc;
1637
border-left: 5px solid #ccc;
17-
margin-bottom: 5px;
1838
padding: 5px;
1939
text-align: center;
2040
color: #888;
@@ -23,46 +43,45 @@
2343
line-height: 25px;
2444
}
2545

26-
.gamelog.pinned .log-event {
27-
opacity: 0.2;
46+
.gamelog .phase-marker {
47+
grid-column: 3;
48+
background: #555;
49+
border: 1px solid #888;
50+
color: #eee;
51+
text-align: center;
52+
font-weight: bold;
53+
padding-top: 10px;
54+
padding-bottom: 10px;
55+
text-orientation: sideways;
56+
writing-mode: vertical-rl;
57+
line-height: 30px;
2858
}
29-
.gamelog.pinned .turn-marker {
59+
60+
.gamelog.pinned .log-event {
3061
opacity: 0.2;
3162
}
3263

3364
.gamelog .log-event:hover {
3465
border-style: solid;
35-
background: #ddffdd;
36-
color: #222;
66+
background: #eee;
3767
}
3868

3969
.gamelog .log-event.pinned {
4070
border-style: solid;
41-
background: #ddffdd;
42-
color: #222;
71+
background: #eee;
4372
opacity: 1;
4473
}
4574

46-
.gamelog .turn-marker {
47-
text-align: center;
48-
font-weight: bold;
49-
margin-bottom: 10px;
50-
}
51-
52-
.gamelog .turn-marker:not(:first-child) {
53-
margin-top: 20px;
54-
}
55-
5675
.gamelog div.player0 {
57-
border-left-color: #001f3f;
76+
border-left-color: #ff851b;
5877
}
5978

6079
.gamelog div.player1 {
61-
border-left-color: #0074d9;
80+
border-left-color: #7fdbff;
6281
}
6382

6483
.gamelog div.player2 {
65-
border-left-color: #7fdbff;
84+
border-left-color: #0074d9;
6685
}
6786

6887
.gamelog div.player3 {
@@ -86,7 +105,7 @@
86105
}
87106

88107
.gamelog div.player8 {
89-
border-left-color: #ff851b;
108+
border-left-color: #001f3f;
90109
}
91110

92111
.gamelog div.player9 {

src/client/log/log.js

Lines changed: 108 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import React from 'react';
1010
import PropTypes from 'prop-types';
11+
import { MAKE_MOVE } from '../../core/action-types';
1112
import './log.css';
1213

1314
/**
@@ -46,12 +47,45 @@ LogEvent.propTypes = {
4647
pinned: PropTypes.bool,
4748
};
4849

49-
const TurnMarker = props => (
50-
<div className="turn-marker">Turn #{props.turn}</div>
51-
);
50+
/**
51+
* TurnMarker
52+
*
53+
* The markers on the left of the log events that indicate
54+
* which turn the event belongs to.
55+
*/
56+
const TurnMarker = props => {
57+
return (
58+
<div className="turn-marker" style={{ gridRow: 'span ' + props.numEvents }}>
59+
{props.turn}
60+
</div>
61+
);
62+
};
5263

5364
TurnMarker.propTypes = {
5465
turn: PropTypes.number.isRequired,
66+
numEvents: PropTypes.number.isRequired,
67+
};
68+
69+
/**
70+
* PhaseMarker
71+
*
72+
* The markers on the right of the log events that indicate
73+
* which phase the event belongs to.
74+
*/
75+
const PhaseMarker = props => {
76+
return (
77+
<div
78+
className="phase-marker"
79+
style={{ gridRow: 'span ' + props.numEvents }}
80+
>
81+
{props.phase}
82+
</div>
83+
);
84+
};
85+
86+
PhaseMarker.propTypes = {
87+
phase: PropTypes.string.isRequired,
88+
numEvents: PropTypes.number.isRequired,
5589
};
5690

5791
/**
@@ -116,38 +150,88 @@ export class GameLog extends React.Component {
116150

117151
render() {
118152
let log = [];
119-
let turn = 1;
120-
let turnDelimiter = true;
153+
let turns = [];
154+
let phases = [];
155+
let eventsInCurrentPhase = 0;
156+
let eventsInCurrentTurn = 0;
157+
let state = this.props.initialState;
121158

159+
let lastAction = 0;
122160
for (let i = 0; i < this.props.log.length; i++) {
123-
if (turnDelimiter) {
124-
turnDelimiter = false;
125-
log.push(<TurnMarker key={'turn' + turn} turn={turn} />);
161+
const action = this.props.log[i];
162+
if (action.type == MAKE_MOVE || !action.automatic) {
163+
lastAction = i;
126164
}
165+
}
127166

167+
for (let i = 0; i < this.props.log.length; i++) {
128168
const action = this.props.log[i];
129-
log.push(
130-
<LogEvent
131-
key={i}
132-
pinned={i === this.state.pinned}
133-
logIndex={i}
134-
onLogClick={this.onLogClick}
135-
onMouseEnter={this.onMouseEnter}
136-
onMouseLeave={this.onMouseLeave}
137-
action={action}
138-
/>
139-
);
140-
141-
if (action.payload.type == 'endTurn') {
142-
turn++;
143-
turnDelimiter = true;
169+
const oldTurn = state.ctx.turn;
170+
const oldPhase = state.ctx.phase;
171+
172+
if (action.type == MAKE_MOVE) {
173+
log.push(
174+
<LogEvent
175+
key={i}
176+
pinned={i === this.state.pinned}
177+
logIndex={i}
178+
onLogClick={this.onLogClick}
179+
onMouseEnter={this.onMouseEnter}
180+
onMouseLeave={this.onMouseLeave}
181+
action={action}
182+
/>
183+
);
184+
185+
eventsInCurrentTurn++;
186+
eventsInCurrentPhase++;
187+
}
188+
189+
if (!action.automatic) {
190+
state = this.props.reducer(state, action);
191+
192+
if (
193+
state.ctx.turn != oldTurn ||
194+
state.ctx.gameover !== undefined ||
195+
i == lastAction
196+
) {
197+
turns.push(
198+
<TurnMarker
199+
key={turns.length}
200+
turn={oldTurn}
201+
numEvents={eventsInCurrentTurn}
202+
/>
203+
);
204+
eventsInCurrentTurn = 0;
205+
}
206+
207+
if (
208+
state.ctx.phase != oldPhase ||
209+
state.ctx.gameover !== undefined ||
210+
i == lastAction
211+
) {
212+
phases.push(
213+
<PhaseMarker
214+
key={phases.length}
215+
phase={oldPhase}
216+
numEvents={eventsInCurrentPhase}
217+
/>
218+
);
219+
eventsInCurrentPhase = 0;
220+
}
144221
}
145222
}
146223

147224
let className = 'gamelog';
148225
if (this.state.pinned !== null) {
149226
className += ' pinned';
150227
}
151-
return <div className={className}>{log}</div>;
228+
229+
return (
230+
<div className={className}>
231+
{turns}
232+
{log}
233+
{phases}
234+
</div>
235+
);
152236
}
153237
}

0 commit comments

Comments
 (0)