From 0d68eeabfb953e9976504c8d27ed08c17208cc02 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sun, 11 Mar 2018 13:11:38 -0400 Subject: [PATCH] Move everything to websockets --- assets/js/app.js | 24 +++++++---- assets/js/services/channel.js | 5 --- lib/chess/store/game.ex | 8 +++- lib/chess_web/channels/game_channel.ex | 60 +++++++++++++++++++++++--- lib/chess_web/channels/user_socket.ex | 2 +- 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/assets/js/app.js b/assets/js/app.js index eb19fa5..3605b72 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -25,28 +25,34 @@ class App extends React.Component { store.dispatch(setGameId(gameId)); - API.getGame(gameId) - .then(response => { - store.dispatch(setPlayer(response.data.player)); - store.dispatch(setGame(response.data)); - }); - this.channel = Channel.gameChannel(gameId); - this.channel.on("game_update", data => { + this.channel.on("game:update", data => { + if (data.player != undefined) { + store.dispatch(setPlayer(data.player)); + }; store.dispatch(setGame(data)); }); + + this.channel.join() + .receive("error", resp => { + console.log("Unable to join", resp); + }); } sendMove(gameId, move) { - API.updateGame(gameId, move); + this.channel.push("game:move", move); } render() { const { store, gameId } = this.props; return ( - + ); } } diff --git a/assets/js/services/channel.js b/assets/js/services/channel.js index ac8eed4..1313eeb 100644 --- a/assets/js/services/channel.js +++ b/assets/js/services/channel.js @@ -4,11 +4,6 @@ const Channel = { gameChannel: (gameId) => { const channel = socket.channel(`game:${gameId}`, {}); - channel.join() - .receive("error", resp => { - console.log("Unable to join", resp); - }); - return channel; }, }; diff --git a/lib/chess/store/game.ex b/lib/chess/store/game.ex index 1f62af8..2f5387d 100644 --- a/lib/chess/store/game.ex +++ b/lib/chess/store/game.ex @@ -32,9 +32,13 @@ defmodule Chess.Store.Game do def change_turn("white"), do: "black" def for_user(user) do + for_user_id(user.id) + end + + def for_user_id(user_id) do from game in Game, - where: game.user_id == ^user.id, - or_where: game.opponent_id == ^user.id + where: game.user_id == ^user_id, + or_where: game.opponent_id == ^user_id end def ordered(query) do diff --git a/lib/chess_web/channels/game_channel.ex b/lib/chess_web/channels/game_channel.ex index b9f7fdf..51970b1 100644 --- a/lib/chess_web/channels/game_channel.ex +++ b/lib/chess_web/channels/game_channel.ex @@ -1,19 +1,69 @@ defmodule ChessWeb.GameChannel do @moduledoc false - use Phoenix.Channel + use ChessWeb, :channel + alias Chess.Store.Game alias Chess.Board - def join("game:" <> _game_id, _params, socket) do - {:ok, socket} + import Chess.Auth, only: [current_user: 1] + + def join("game:" <> game_id, _params, socket) do + send(self, {:after_join, game_id}) + + {:ok, assign(socket, :game_id, game_id)} end - def update_game(game) do + def handle_info({:after_join, game_id}, socket) do + game = + socket.assigns.current_user_id + |> Game.for_user_id() + |> Repo.get!(game_id) + + payload = %{ + player: player(socket, game), + board: Board.transform(game.board), + turn: game.turn + } + push(socket, "game:update", payload) + + {:noreply, socket} + end + + def handle_in("game:move", move_params, socket) do + game = + socket.assigns.current_user_id + |> Game.for_user_id() + |> Repo.get!(socket.assigns.game_id) + + changeset = Game.changeset( + game, %{ + board: Board.move_piece(game.board, move_params), + turn: Game.change_turn(game.turn) + } + ) + + case Repo.update(changeset) do + {:ok, game} -> + send_update(game) + + {:noreply, socket} + end + end + + def send_update(game) do payload = %{ board: Board.transform(game.board), turn: game.turn } - ChessWeb.Endpoint.broadcast("game:#{game.id}", "game_update", payload) + ChessWeb.Endpoint.broadcast("game:#{game.id}", "game:update", payload) + end + + defp player(socket, game) do + if game.user_id == socket.assigns.current_user_id do + "white" + else + "black" + end end end diff --git a/lib/chess_web/channels/user_socket.ex b/lib/chess_web/channels/user_socket.ex index cc9378e..d6c27ab 100644 --- a/lib/chess_web/channels/user_socket.ex +++ b/lib/chess_web/channels/user_socket.ex @@ -24,7 +24,7 @@ defmodule ChessWeb.UserSocket do def connect(%{"token" => token}, socket) do case Token.verify(socket, "game socket", token, max_age: 1_209_600) do {:ok, user_id} -> - {:ok, assign(socket, :current_user, user_id)} + {:ok, assign(socket, :current_user_id, user_id)} {:error, _reason} -> :error end