Skip to content

Commit 69bb319

Browse files
author
hiukim
committed
part 7 - wrapping up
1 parent b5c9a39 commit 69bb319

File tree

10 files changed

+204
-87
lines changed

10 files changed

+204
-87
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
node_modules/
1+
node_modules/
2+
.DS_Store

.meteor/packages

+2
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ react-meteor-data
2121
accounts-password
2222
aldeed:simple-schema
2323
mdg:validated-method
24+
semantic:ui-css
25+
fourseven:scss

.meteor/versions

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ejson@1.0.12
2828
email@1.1.16
2929
es5-shim@4.6.13
3030
fastclick@1.0.12
31+
fourseven:scss@3.8.1
3132
geojson-utils@1.0.9
3233
hot-code-push@1.0.4
3334
html-tools@1.0.10
@@ -64,6 +65,7 @@ reactive-var@1.0.10
6465
reload@1.1.10
6566
retry@1.0.8
6667
routepolicy@1.0.11
68+
semantic:ui-css@2.1.2
6769
service-configuration@1.0.10
6870
sha@1.0.8
6971
spacebars@1.0.12

client/main.css

-6
This file was deleted.

client/main.scss

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
table.game-board {
2+
margin: auto;
3+
4+
tr td {
5+
border: 1px solid black;
6+
width: 80px;
7+
height: 80px;
8+
font-size: 80px;
9+
text-align: center;
10+
}
11+
}

imports/ui/App.jsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ class App extends Component {
1313
}
1414
}
1515

16-
handleEnterGame(gameId) {
16+
handleEnterGame(gameId) {
1717
this.setState({selectedGameId: gameId});
1818
}
1919

20-
handleBackToGameList() {
20+
handleBackToGameList() {
2121
this.setState({selectedGameId: null});
2222
}
2323

24-
selectedGame() {
24+
selectedGame() {
2525
let selectedGame = _.find(this.props.games, (game) => {
2626
return game._id === this.state.selectedGameId;
2727
});
2828
return selectedGame;
2929
}
3030

31-
render() {
31+
render() {
3232
if (!this.props.user) {
3333
return (
3434
<div>
@@ -37,7 +37,7 @@ render() {
3737
)
3838
}
3939

40-
if (this.state.selectedGameId === null) {
40+
if (this.state.selectedGameId === null) {
4141
return (
4242
<GameList
4343
games={this.props.games}

imports/ui/GameBoard.jsx

+52-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { Component } from 'react';
2-
import {GamesController} from '../api/controllers/gamesController.js';
2+
import GameHeader from './GameHeader.jsx';
33
import {Game, GameStatuses} from '../api/models/game.js';
44
import {userMarkGame} from '../api/methods/games.js';
55

@@ -10,11 +10,11 @@ export default class GameBoard extends Component {
1010
userMarkGame.call({gameId: game._id, row: row, col: col});
1111
}
1212

13-
handleBackToGameList() {
13+
handleBackToGameList() {
1414
this.props.backToGameListHandler();
1515
}
1616

17-
renderCell(row, col) {
17+
renderCell(row, col) {
1818
let value = this.props.game.board[row][col];
1919
if (value === 0) return (<td>O</td>);
2020
if (value === 1) return (<td>X</td>);
@@ -23,12 +23,12 @@ renderCell(row, col) {
2323
);
2424
}
2525

26-
renderStatus() {
26+
renderStatus() {
2727
let game = this.props.game;
2828
let status = "";
2929
if (game.status === GameStatuses.STARTED) {
3030
let playerIndex = game.currentPlayerIndex();
31-
status = `In Progress: current player: ${game.players[playerIndex].username}`;
31+
status = `Current player: ${game.players[playerIndex].username}`;
3232
} else if (game.status === GameStatuses.FINISHED) {
3333
let playerIndex = game.winner();
3434
if (playerIndex === null) {
@@ -38,35 +38,58 @@ renderStatus() {
3838
}
3939
}
4040

41-
return (
41+
return (
4242
<div>{status}</div>
4343
)
4444
}
4545

46-
render() {
46+
render() {
4747
return (
48-
<div>
49-
<button onClick={this.handleBackToGameList.bind(this)}>Back</button>
50-
{this.renderStatus()}
51-
<table className="game-board">
52-
<tbody>
53-
<tr>
54-
{this.renderCell(0, 0)}
55-
{this.renderCell(0, 1)}
56-
{this.renderCell(0, 2)}
57-
</tr>
58-
<tr>
59-
{this.renderCell(1, 0)}
60-
{this.renderCell(1, 1)}
61-
{this.renderCell(1, 2)}
62-
</tr>
63-
<tr>
64-
{this.renderCell(2, 0)}
65-
{this.renderCell(2, 1)}
66-
{this.renderCell(2, 2)}
67-
</tr>
68-
</tbody>
69-
</table>
48+
<div className="ui container">
49+
<GameHeader user={this.props.user}/>
50+
51+
<button className="ui button blue" onClick={this.handleBackToGameList.bind(this)}>Back to Lobby</button>
52+
53+
<div className="ui top attached header">
54+
<div className="ui grid">
55+
<div className="ui three column center aligned row">
56+
<div className="ui column">
57+
{this.props.game.players[0].username} <br/>O
58+
</div>
59+
<div className="ui column">
60+
v.s.
61+
</div>
62+
<div className="ui column">
63+
{this.props.game.players[1].username} <br/>X
64+
</div>
65+
</div>
66+
</div>
67+
</div>
68+
<div className="ui attached center aligned segment">
69+
{this.renderStatus()}
70+
</div>
71+
72+
<div className="ui attached segment">
73+
<table className="game-board">
74+
<tbody>
75+
<tr>
76+
{this.renderCell(0, 0)}
77+
{this.renderCell(0, 1)}
78+
{this.renderCell(0, 2)}
79+
</tr>
80+
<tr>
81+
{this.renderCell(1, 0)}
82+
{this.renderCell(1, 1)}
83+
{this.renderCell(1, 2)}
84+
</tr>
85+
<tr>
86+
{this.renderCell(2, 0)}
87+
{this.renderCell(2, 1)}
88+
{this.renderCell(2, 2)}
89+
</tr>
90+
</tbody>
91+
</table>
92+
</div>
7093
</div>
7194
)
7295
}

imports/ui/GameHeader.jsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { Component } from 'react';
2+
3+
export default class GameBoard extends Component {
4+
handleLogout() {
5+
Meteor.logout();
6+
}
7+
render() {
8+
return (
9+
<div className="ui menu inverted">
10+
<div className="header item">
11+
Online Tic-Tac-Toe
12+
</div>
13+
14+
{this.props.user? (
15+
<div className="right menu">
16+
<div className="item">
17+
<i className="meh icon"/>
18+
{this.props.user.username}
19+
</div>
20+
<a className="item" onClick={this.handleLogout.bind(this)}>
21+
Logout
22+
</a>
23+
</div>
24+
): null}
25+
</div>
26+
)
27+
}
28+
}

imports/ui/GameList.jsx

+68-39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { Component } from 'react';
2-
import {GamesController} from '../api/controllers/gamesController.js';
2+
import GameHeader from './GameHeader.jsx';
33
import {Game, GameStatuses} from '../api/models/game.js';
44
import {newGame, userJoinGame, userLeaveGame} from '../api/methods/games.js';
55

@@ -12,71 +12,100 @@ export default class GameList extends Component {
1212
userLeaveGame.call({gameId: gameId});
1313
}
1414

15-
handleJoinGame(gameId) {
15+
handleJoinGame(gameId) {
1616
userJoinGame.call({gameId: gameId});
1717
}
1818

19-
handleEnterGame(gameId) {
19+
handleEnterGame(gameId) {
2020
this.props.enterGameHandler(gameId);
2121
}
2222

23-
activeGames() {
23+
activeGames() {
2424
return _.filter(this.props.games, (game) => {
2525
return game.status === GameStatuses.WAITING || game.status === GameStatuses.STARTED;
2626
});
2727
}
2828

29-
myCurrentGameId() {
29+
myCurrentGameId() {
3030
let game = _.find(this.activeGames(), (game) => {
3131
return game.userIndex(this.props.user) !== null;
3232
});
3333
return game === undefined? null: game._id;
3434
}
3535

36-
renderPlayers(game) {
37-
let player1 = game.players.length > 0? game.players[0].username: '';
38-
let player2 = game.players.length > 1? game.players[1].username: '';
36+
renderPlayers(game) {
37+
let player1 = game.players.length > 0? game.players[0].username: '(waiting)';
38+
let player2 = game.players.length > 1? game.players[1].username: '(waiting)';
3939
return (
40-
<span>[{player1}] vs [{player2}]</span>
40+
<div>
41+
<div>
42+
<i className="user icon"></i> {player1}
43+
</div>
44+
<div>
45+
<i className="user icon"></i> {player2}
46+
</div>
47+
</div>
4148
)
4249
}
4350

44-
render() {
51+
render() {
4552
return (
46-
<div>
47-
<div>
48-
<h1>List of games</h1>
49-
{this.activeGames().map((game, index) => {
50-
return (
51-
<div key={game._id}>
52-
<span>Game {index+1}</span>
53-
{this.renderPlayers(game)}
53+
<div className="ui container">
54+
<GameHeader user={this.props.user}/>
5455

55-
{/* can leave only if user is in the game, and the game is not started */}
56-
{this.myCurrentGameId() === game._id && game.status === GameStatuses.WAITING? (
57-
<button onClick={this.handleLeaveGame.bind(this, game._id)}>Leave</button>
58-
): null}
56+
<h1 className="ui top attached header">List of games</h1>
57+
<div className="ui attached segment">
58+
<div className="ui three cards">
59+
{this.activeGames().map((game, index) => {
60+
return (
61+
<div key={game._id} className="ui card">
62+
<div className="content">
63+
<div className="header">
64+
{game.status === GameStatuses.WAITING? (
65+
<span className="ui right yellow corner label">
66+
<i className="idea icon"/>
67+
</span>
68+
): null}
69+
Game {index+1}
70+
</div>
71+
</div>
72+
<div className="content">
73+
{this.renderPlayers(game)}
74+
</div>
5975

60-
{/* can join only if user is not in any game, and the game is not started */}
61-
{this.myCurrentGameId() === null && game.status === GameStatuses.WAITING? (
62-
<button onClick={this.handleJoinGame.bind(this, game._id)}>Join</button>
63-
): null}
76+
<div className="extra content">
77+
{/* can leave only if user is in the game, and the game is not started */}
78+
{this.myCurrentGameId() === game._id && game.status === GameStatuses.WAITING? (
79+
<button className="ui red button" onClick={this.handleLeaveGame.bind(this, game._id)}>Leave</button>
80+
): null}
6481

65-
{/* can enter only if the game is started */}
66-
{game.status === GameStatuses.STARTED? (
67-
<button onClick={this.handleEnterGame.bind(this, game._id)}>Enter</button>
68-
): null}
69-
</div>
70-
)
71-
})}
72-
</div>
82+
{/* can join only if user is not in any game, and the game is not started */}
83+
{this.myCurrentGameId() === null && game.status === GameStatuses.WAITING? (
84+
<button className="ui green button" onClick={this.handleJoinGame.bind(this, game._id)}>Join</button>
85+
): null}
7386

74-
{/* Only show new game button if player is not in any room */}
75-
{this.myCurrentGameId() === null? (
76-
<div>
77-
<button onClick={this.handleNewGame.bind(this)}>New Game</button>
87+
{/* can enter only if the game is started */}
88+
{game.status === GameStatuses.STARTED? (
89+
<button className="ui blue button" onClick={this.handleEnterGame.bind(this, game._id)}>Enter</button>
90+
): null}
91+
92+
{/* just a invisible dummy button to make up the space */}
93+
<button className="ui button" style={{visibility: "hidden"}}>Dummy</button>
94+
</div>
95+
</div>
96+
)
97+
})}
7898
</div>
79-
): null}
99+
100+
{/* Only show new game button if player is not in any room */}
101+
</div>
102+
<div className="ui attached segment">
103+
{this.myCurrentGameId() === null? (
104+
<div>
105+
<button className="ui green button" onClick={this.handleNewGame.bind(this)}>New Game</button>
106+
</div>
107+
): null}
108+
</div>
80109
</div>
81110
)
82111
}

0 commit comments

Comments
 (0)