-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mehdi Necibi
committed
Oct 23, 2023
1 parent
b318c70
commit 37973e8
Showing
13 changed files
with
366 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
defmodule ClusterTestWeb.Presence do | ||
@moduledoc """ | ||
Provides presence tracking to channels and processes. | ||
See the [`Phoenix.Presence`](https://hexdocs.pm/phoenix/Phoenix.Presence.html) | ||
docs for more details. | ||
""" | ||
use Phoenix.Presence, | ||
otp_app: :cluster_test, | ||
pubsub_server: ClusterTest.PubSub | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
defmodule ClusterTestWeb.PageController do | ||
use ClusterTestWeb, :controller | ||
|
||
def home(conn, _params) do | ||
# The home page is often custom made, | ||
# so skip the default app layout. | ||
render(conn, :home, layout: false) | ||
def index(conn, _params) do | ||
session = conn |> get_session() | ||
|
||
case session do | ||
%{"user" => _user} -> | ||
conn | ||
|> redirect(to: "/cursors") | ||
|
||
_ -> | ||
conn | ||
|> put_session(:user, ClusterTestWeb.Names.generate()) | ||
|> configure_session(renew: true) | ||
|> redirect(to: "/cursors") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
defmodule ClusterTestWeb.CursorPositionsLive.Index do | ||
alias ClusterTestWeb.Presence | ||
|
||
use ClusterTestWeb, :live_view | ||
|
||
@clustertest "clustertest" | ||
|
||
@impl true | ||
def mount(_params, %{"user" => user}, socket) do | ||
Presence.track(self(), @clustertest, socket.id, %{ | ||
socket_id: socket.id, | ||
x: 50, | ||
y: 50, | ||
name: user | ||
}) | ||
|
||
ClusterTestWeb.Endpoint.subscribe(@clustertest) | ||
|
||
initial_users = | ||
Presence.list(@clustertest) | ||
|> Enum.map(fn {_, data} -> data[:metas] |> List.first() end) | ||
|
||
updated = | ||
socket | ||
|> assign(:user, user) | ||
|> assign(:users, initial_users) | ||
|> assign(:socket_id, socket.id) | ||
|
||
{:ok, updated} | ||
end | ||
|
||
@impl true | ||
def handle_event("cursor-move", %{"x" => x, "y" => y}, socket) do | ||
key = socket.id | ||
payload = %{x: x, y: y} | ||
|
||
metas = | ||
Presence.get_by_key(@clustertest, key)[:metas] | ||
|> List.first() | ||
|> Map.merge(payload) | ||
|
||
Presence.update(self(), @clustertest, key, metas) | ||
|
||
{:noreply, socket} | ||
end | ||
|
||
@impl true | ||
def handle_info(%{event: "presence_diff", payload: _payload}, socket) do | ||
users = | ||
Presence.list(@clustertest) | ||
|> Enum.map(fn {_, data} -> data[:metas] |> List.first() end) | ||
|
||
updated = | ||
socket | ||
|> assign(users: users) | ||
|> assign(socket_id: socket.id) | ||
|
||
{:noreply, updated} | ||
end | ||
|
||
@impl true | ||
def render(assigns) do | ||
~H""" | ||
<.header> | ||
Listing Cursor positions | ||
</.header> | ||
<div> | ||
<div>Current node: <%= node() %></div> | ||
<div>Other nodes: <%= "[#{Enum.join(Node.list(), ",")}]" %></div> | ||
<div> | ||
<ul class="list-none" id="cursors" phx-hook="TrackClientCursor"> | ||
<%= for user <- @users do %> | ||
<li | ||
style={"color: deeppink; left: #{user.x}%; top: #{user.y}%"} | ||
class="flex flex-col absolute pointer-events-none whitespace-nowrap overflow-hidden" | ||
> | ||
<svg | ||
version="1.1" | ||
width="25px" | ||
height="25px" | ||
xmlns="http://www.w3.org/2000/svg" | ||
xmlns:xlink="http://www.w3.org/1999/xlink" | ||
viewBox="0 0 21 21" | ||
> | ||
<polygon fill="black" points="8.2,20.9 8.2,4.9 19.8,16.5 13,16.5 12.6,16.6" /> | ||
<polygon fill="currentColor" points="9.2,7.3 9.2,18.5 12.2,15.6 12.6,15.5 17.4,15.5" /> | ||
</svg> | ||
<span style="background-color: deeppink;" class="mt-1 ml-4 px-1 text-sm text-white"> | ||
<%= user.name %> | ||
</span> | ||
</li> | ||
<% end %> | ||
</ul> | ||
</div> | ||
</div> | ||
""" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
defmodule ClusterTestWeb.Names do | ||
def generate do | ||
title = ~w(Sir Sr Prof Saint Ibn Lady Madam Mistress Herr Dr) |> Enum.random() | ||
|
||
name = | ||
[ | ||
~w(B C D F G H J K L M N P Q R S T V W X Z), | ||
~w(o a i ij e ee u uu oo aj aa oe ou eu), | ||
~w(b c d f g h k l m n p q r s t v w x z), | ||
~w(o a i ij e ee u uu oo aj aa oe ou eu) | ||
] | ||
|> Enum.map(fn l -> Enum.random(l) end) | ||
|> Enum.join() | ||
|
||
"#{title} #{name}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
priv/repo/migrations/20231023203353_create_cursor_positions.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
defmodule ClusterTest.Repo.Migrations.CreateCursorPositions do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:cursor_positions) do | ||
add :x, :integer | ||
add :y, :integer | ||
|
||
timestamps(type: :utc_datetime) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
defmodule ClusterTest.CursorTest do | ||
use ClusterTest.DataCase | ||
|
||
alias ClusterTest.Cursor | ||
|
||
describe "cursor_positions" do | ||
alias ClusterTest.Cursor.CursorPositions | ||
|
||
import ClusterTest.CursorFixtures | ||
|
||
@invalid_attrs %{y: nil, x: nil} | ||
|
||
test "list_cursor_positions/0 returns all cursor_positions" do | ||
cursor_positions = cursor_positions_fixture() | ||
assert Cursor.list_cursor_positions() == [cursor_positions] | ||
end | ||
|
||
test "get_cursor_positions!/1 returns the cursor_positions with given id" do | ||
cursor_positions = cursor_positions_fixture() | ||
assert Cursor.get_cursor_positions!(cursor_positions.id) == cursor_positions | ||
end | ||
|
||
test "create_cursor_positions/1 with valid data creates a cursor_positions" do | ||
valid_attrs = %{y: 42, x: 42} | ||
|
||
assert {:ok, %CursorPositions{} = cursor_positions} = Cursor.create_cursor_positions(valid_attrs) | ||
assert cursor_positions.y == 42 | ||
assert cursor_positions.x == 42 | ||
end | ||
|
||
test "create_cursor_positions/1 with invalid data returns error changeset" do | ||
assert {:error, %Ecto.Changeset{}} = Cursor.create_cursor_positions(@invalid_attrs) | ||
end | ||
|
||
test "update_cursor_positions/2 with valid data updates the cursor_positions" do | ||
cursor_positions = cursor_positions_fixture() | ||
update_attrs = %{y: 43, x: 43} | ||
|
||
assert {:ok, %CursorPositions{} = cursor_positions} = Cursor.update_cursor_positions(cursor_positions, update_attrs) | ||
assert cursor_positions.y == 43 | ||
assert cursor_positions.x == 43 | ||
end | ||
|
||
test "update_cursor_positions/2 with invalid data returns error changeset" do | ||
cursor_positions = cursor_positions_fixture() | ||
assert {:error, %Ecto.Changeset{}} = Cursor.update_cursor_positions(cursor_positions, @invalid_attrs) | ||
assert cursor_positions == Cursor.get_cursor_positions!(cursor_positions.id) | ||
end | ||
|
||
test "delete_cursor_positions/1 deletes the cursor_positions" do | ||
cursor_positions = cursor_positions_fixture() | ||
assert {:ok, %CursorPositions{}} = Cursor.delete_cursor_positions(cursor_positions) | ||
assert_raise Ecto.NoResultsError, fn -> Cursor.get_cursor_positions!(cursor_positions.id) end | ||
end | ||
|
||
test "change_cursor_positions/1 returns a cursor_positions changeset" do | ||
cursor_positions = cursor_positions_fixture() | ||
assert %Ecto.Changeset{} = Cursor.change_cursor_positions(cursor_positions) | ||
end | ||
end | ||
end |
Oops, something went wrong.