1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00

Opponent finder in LiveView

This commit is contained in:
Daniel Barber 2023-10-25 16:21:14 -05:00
parent 2314dc6a19
commit e30627b3ac
3 changed files with 89 additions and 1 deletions

View File

@ -4,7 +4,12 @@
<%= form_for @changeset, game_path(@conn, :create), [class: "create-game"],
fn form -> %>
<div class="form-group">
<div id="opponent-finder"></div>
<%= live_render(
@conn,
ChessWeb.OpponentFinderLive,
session: %{"user_id" => current_user(@conn).id}
) %>
<%= error_tag form, :opponent_id %>
</div>

View File

@ -0,0 +1,32 @@
<div class="form-group">
<div class="form-field opponent-finder">
<label for="query-string">Find opponent</label>
<%= tag :input,
id: "query-string",
class: "search-input",
name: "q",
type: "text",
autocomplete: "off",
"phx-change": "search",
"phx-debounce": "250",
value: @q,
placeholder: Map.get(@selected, :name, "")
%>
<%= tag :input,
name: "game[opponent_id]",
type: "hidden",
value: Map.get(@selected, :id, nil)
%>
<%= if Enum.any?(@opponents) do %>
<ul class="opponent-finder__result">
<%= for opponent <- @opponents do %>
<li><a class="opponent-finder__result-item"
phx-click="select" phx-value-id="<%= opponent.id
%>" href="#"><%= opponent.name %></a></li>
<% end %>
</ul>
<% end %>
</div>
</div>

View File

@ -0,0 +1,51 @@
defmodule ChessWeb.OpponentFinderLive do
use Phoenix.LiveView
alias Chess.Store.User
alias Chess.Repo
alias Chess.Repo.Queries
alias ChessWeb.GameView
def render(assigns) do
Phoenix.View.render(GameView, "opponent_finder.html", assigns)
end
def mount(_params, %{"user_id" => user_id}, socket) do
ChessWeb.Endpoint.subscribe("opponent_finder:#{user_id}")
user = Repo.get!(User, user_id)
{:ok, assign(socket, default_assigns(user))}
end
def handle_event("search", %{"q" => q}, socket) do
opponents =
case q do
"" ->
[]
query_string ->
socket.assigns.user
|> Queries.opponents(query_string)
|> Repo.all()
end
{:noreply, assign(socket, %{opponents: opponents})}
end
def handle_event("select", %{"id" => id}, socket) do
opponent = Repo.get!(User, id)
{:noreply, assign(socket, %{q: "", opponents: [], selected: opponent})}
end
def default_assigns(user) do
%{
q: "",
user: user,
opponents: [],
selected: %{}
}
end
end