diff --git a/assets/css/_game_grid.scss b/assets/css/_game_grid.scss
index a2af715..03fc68b 100644
--- a/assets/css/_game_grid.scss
+++ b/assets/css/_game_grid.scss
@@ -1,7 +1,24 @@
.game-grid {
display: grid;
grid-gap: $base-spacing;
- grid-template-areas: "board moves";
- grid-template-columns: min-content 1fr;
- grid-template-rows: var(--board-size);
+}
+
+@media (min-aspect-ratio: 10/11) {
+ .game-grid {
+ grid-template-areas:
+ "board game-info"
+ "board move-list";
+ grid-template-columns: min-content 1fr;
+ grid-template-rows: min-content 1fr;
+ }
+}
+
+@media (max-aspect-ratio: 10/11) {
+ .game-grid {
+ grid-template-areas:
+ "game-info"
+ "board"
+ "move-list";
+ grid-template-rows: min-content min-content min-content;
+ }
}
diff --git a/assets/css/_game_info.scss b/assets/css/_game_info.scss
new file mode 100644
index 0000000..746bb80
--- /dev/null
+++ b/assets/css/_game_info.scss
@@ -0,0 +1,3 @@
+.game-info {
+ grid-area: game-info;
+}
diff --git a/assets/css/_layout.scss b/assets/css/_layout.scss
index 25d5eb5..1c01222 100644
--- a/assets/css/_layout.scss
+++ b/assets/css/_layout.scss
@@ -20,6 +20,10 @@ h1 {
margin: 0;
}
+main {
+ margin-top: 5vmin;
+}
+
.container {
margin: 0 auto;
width: 90%;
diff --git a/assets/css/_move_list.scss b/assets/css/_move_list.scss
index 235f151..ab3eabb 100644
--- a/assets/css/_move_list.scss
+++ b/assets/css/_move_list.scss
@@ -1,5 +1,5 @@
.move-list {
- grid-area: moves;
+ grid-area: move-list;
overflow-y: auto;
}
diff --git a/assets/css/app.scss b/assets/css/app.scss
index e55b32d..76bbed1 100644
--- a/assets/css/app.scss
+++ b/assets/css/app.scss
@@ -15,4 +15,5 @@
@import "game_list";
@import "board";
@import "move_list";
+@import "game_info";
@import "game_grid";
diff --git a/assets/js/app.js b/assets/js/app.js
index dcb8d3f..adb6cd8 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -14,6 +14,7 @@ import { setGameId } from "./store/actions";
import ChessBoard from "./components/chess-board";
import MoveList from "./components/move-list";
+import GameInfo from "./components/game-info";
const store = createStore(chessBoardReducer);
@@ -31,6 +32,11 @@ class App extends React.Component {
return store.getState().moves;
}
+ get opponent() {
+ const { store } = this.props;
+ return store.getState().opponent;
+ }
+
render() {
const { store, gameId } = this.props;
@@ -42,6 +48,8 @@ class App extends React.Component {
channel={this.channel}
/>
+
+
);
diff --git a/assets/js/components/game-info.js b/assets/js/components/game-info.js
new file mode 100644
index 0000000..904028f
--- /dev/null
+++ b/assets/js/components/game-info.js
@@ -0,0 +1,18 @@
+import React from "react";
+import { connect } from "react-redux";
+
+const GameInfo = (props) => {
+ return (
+
+
Playing {props.opponent}
+
+ );
+};
+
+const mapStateToProps = (state) => {
+ return {
+ opponent: state.opponent,
+ };
+};
+
+export default connect(mapStateToProps)(GameInfo);
diff --git a/assets/js/reducers/chess-board.js b/assets/js/reducers/chess-board.js
index beb47eb..298c239 100644
--- a/assets/js/reducers/chess-board.js
+++ b/assets/js/reducers/chess-board.js
@@ -9,6 +9,11 @@ const chessBoardReducer = (state = defaultState, action) => {
.set("player", action.player)
.toJS();
+ case "SET_OPPONENT":
+ return Immutable.fromJS(state)
+ .set("opponent", action.opponent)
+ .toJS();
+
case "SET_GAME":
return Immutable.fromJS(state)
.set("board", action.board)
diff --git a/assets/js/services/channel.js b/assets/js/services/channel.js
index 73989c1..6f30a0c 100644
--- a/assets/js/services/channel.js
+++ b/assets/js/services/channel.js
@@ -1,5 +1,5 @@
import socket from "../socket";
-import { setPlayer, setGame, setAvailableMoves } from "../store/actions";
+import { setPlayer, setOpponent, setGame, setAvailableMoves } from "../store/actions";
class Channel {
constructor(store, gameId) {
@@ -21,6 +21,7 @@ class Channel {
this.channel.on("game:update", data => {
if (data.player != undefined) {
this.store.dispatch(setPlayer(data.player));
+ this.store.dispatch(setOpponent(data.opponent));
}
this.store.dispatch(setGame(data));
});
diff --git a/assets/js/store/actions.js b/assets/js/store/actions.js
index c4b1b0c..9d6ee7b 100644
--- a/assets/js/store/actions.js
+++ b/assets/js/store/actions.js
@@ -1,4 +1,5 @@
const SET_PLAYER = "SET_PLAYER";
+const SET_OPPONENT = "SET_OPPONENT";
const SET_GAME = "SET_GAME";
const SET_AVAILABLE_MOVES = "SET_AVAILABLE_MOVES";
const SET_GAME_ID = "SET_GAME_ID";
@@ -11,6 +12,13 @@ export const setPlayer = (player) => {
};
};
+export const setOpponent = (opponent) => {
+ return {
+ type: SET_OPPONENT,
+ opponent,
+ };
+};
+
export const setGame = (data) => {
return {
type: SET_GAME,
diff --git a/assets/js/store/default-state.js b/assets/js/store/default-state.js
index 0dfc0f2..9fc5c61 100644
--- a/assets/js/store/default-state.js
+++ b/assets/js/store/default-state.js
@@ -2,6 +2,7 @@ const defaultState = {
selectedSquare: null,
player: null,
+ opponent: null,
turn: null,
state: null,
diff --git a/lib/chess_web/channels/game_channel.ex b/lib/chess_web/channels/game_channel.ex
index aea15aa..39763f5 100644
--- a/lib/chess_web/channels/game_channel.ex
+++ b/lib/chess_web/channels/game_channel.ex
@@ -21,10 +21,13 @@ defmodule ChessWeb.GameChannel do
socket.assigns.current_user_id
|> Game.for_user_id()
|> preload(:moves)
+ |> preload(:user)
+ |> preload(:opponent)
|> Repo.get!(game_id)
payload = %{
player: player(socket, game),
+ opponent: opponent(socket, game),
board: Board.transform(game.board),
turn: game.turn,
state: game.state,
@@ -116,4 +119,12 @@ defmodule ChessWeb.GameChannel do
"black"
end
end
+
+ defp opponent(socket, game) do
+ if game.user_id == socket.assigns.current_user_id do
+ game.opponent.name
+ else
+ game.user.name
+ end
+ end
end
diff --git a/lib/chess_web/templates/game/show.html.eex b/lib/chess_web/templates/game/show.html.eex
index 18255f9..9c68a44 100644
--- a/lib/chess_web/templates/game/show.html.eex
+++ b/lib/chess_web/templates/game/show.html.eex
@@ -1,4 +1,2 @@
-<%= gettext "Game with %{name}", name: opponent(@conn, @game).name %>
-