1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00
chess/lib/chess_web/views/live/game_info_live.ex

73 lines
1.8 KiB
Elixir

defmodule ChessWeb.GameInfoLive do
use Phoenix.LiveView
alias Chess.Store.User
alias Chess.Store.Game
alias Chess.Store.Move
alias Chess.Repo
alias ChessWeb.Presence
import Ecto.Query
require Logger
def render(assigns) do
Phoenix.View.render(ChessWeb.GameView, "game_info.html", assigns)
end
def mount(_params, %{"game_id" => game_id, "user_id" => user_id}, socket) do
topic = "game:#{game_id}"
ChessWeb.Endpoint.subscribe(topic)
user = Repo.get!(User, user_id)
game =
Game.for_user(user)
|> preload(:user)
|> preload(:opponent)
|> preload(
moves:
^from(
move in Move,
order_by: [asc: move.inserted_at]
)
)
|> Repo.get!(game_id)
Presence.track(self(), topic, :user, %{id: user_id})
{:ok, assign(socket, game: game, user: user, presence: presence_list(topic))}
end
def handle_info(%{event: "move", payload: state}, socket) do
{:noreply, assign(socket, state)}
end
def handle_info(
%{event: "presence_diff", payload: %{joins: joins, leaves: leaves}},
socket
) do
{:noreply, socket |> handle_joins(joins) |> handle_leaves(leaves)}
end
defp presence_list(topic) do
Presence.list(topic)
|> Map.get("user")
|> Map.get(:metas)
|> Map.new(fn meta -> {meta.id, meta} end)
end
defp handle_joins(socket, joins) do
Enum.reduce(joins, socket, fn {"user", %{metas: [meta | _]}}, socket ->
assign(socket, :presence, Map.put(socket.assigns.presence, meta.id, meta))
end)
end
defp handle_leaves(socket, leaves) do
Enum.reduce(leaves, socket, fn {"user", %{metas: [meta | _]}}, socket ->
assign(socket, :presence, Map.delete(socket.assigns.presence, meta.id))
end)
end
end