-
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
Johnny Mikhael
committed
Feb 7, 2022
1 parent
0f1278b
commit c3ebe39
Showing
15 changed files
with
301 additions
and
3 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,84 @@ | ||
// NOTE: The contents of this file will only be executed if | ||
// you uncomment its entry in "assets/js/app.js". | ||
|
||
// Bring in Phoenix channels client library: | ||
import { Socket, Presence } from 'phoenix'; | ||
|
||
function cursorTemplate({ x, y, name, color }) { | ||
const li = document.createElement('li'); | ||
li.classList = | ||
'flex flex-col absolute pointer-events-none whitespace-nowrap overflow-hidden'; | ||
li.style.left = x + 'px'; | ||
li.style.top = y + 'px'; | ||
li.style.color = color; | ||
|
||
li.innerHTML = ` | ||
<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 class="mt-1 ml-4 px-1 text-sm text-white" /> | ||
`; | ||
|
||
li.lastChild.style.backgroundColor = color; | ||
li.lastChild.textContent = name; | ||
|
||
return li; | ||
} | ||
|
||
// And connect to the path in "lib/my_button_app_web/endpoint.ex". We pass the | ||
// token for authentication. Read below how it should be used. | ||
// {params: {token: window.userToken}} | ||
let socket = new Socket('/socket', { | ||
params: { token: sessionStorage.userToken } | ||
}); | ||
socket.connect() | ||
|
||
// Now that you are connected, you can join channels with a topic. | ||
// Let's assume you have a channel with a topic named `room` and the | ||
// subtopic is its id - in this case 42: | ||
let channel = socket.channel("cursor:lobby", {}) | ||
channel.join() | ||
.receive('ok', (resp) => { | ||
console.log('Joined successfully', resp); | ||
document.addEventListener('mousemove', (e) => { | ||
const x = e.pageX / window.innerWidth; | ||
const y = e.pageY / window.innerHeight; | ||
channel.push('move', { x, y }); | ||
}); | ||
|
||
}) | ||
.receive('error', (resp) => { | ||
console.log('Unable to join', resp); | ||
}); | ||
|
||
const presence = new Presence(channel); | ||
presence.onSync(() => { | ||
const ul = document.createElement('ul'); | ||
|
||
presence.list((name, { metas: [firstDevice] }) => { | ||
const { x, y, color } = firstDevice; | ||
const cursorLi = cursorTemplate({ | ||
name, | ||
x: x * window.innerWidth, | ||
y: y * window.innerHeight, | ||
color | ||
}); | ||
ul.appendChild(cursorLi); | ||
}); | ||
|
||
document.getElementById('cursor-list').innerHTML = ul.innerHTML; | ||
}); | ||
|
||
export default socket |
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,25 @@ | ||
defmodule MyButtonApp.Names do | ||
|
||
@moduledoc false | ||
|
||
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 | ||
|
||
def getHSL(s) do | ||
hue = to_charlist(s) |> Enum.sum() |> rem(360) | ||
"hsl(#{hue}, 70%, 40%)" | ||
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,65 @@ | ||
defmodule MyButtonAppWeb.CursorChannel do | ||
|
||
alias MyButtonAppWeb.Presence | ||
use MyButtonAppWeb, :channel | ||
|
||
@impl true | ||
def handle_in("move", %{"x" => x, "y" => y}, socket) do | ||
{:ok, _} = | ||
Presence.update(socket, socket.assigns.current_user, fn previousState -> | ||
Map.merge(previousState, | ||
%{ | ||
online_at: inspect(System.system_time(:second)), | ||
color: MyButtonApp.Names.getHSL(socket.assigns.current_user), | ||
x: x, | ||
y: y | ||
} | ||
) | ||
end) | ||
|
||
{:noreply, socket} | ||
end | ||
|
||
@impl true | ||
def join("cursor:lobby", payload, socket) do | ||
send(self(), :after_join) | ||
|
||
if authorized?(payload) do | ||
{:ok, socket} | ||
else | ||
{:error, %{reason: "unauthorized"}} | ||
end | ||
end | ||
|
||
@impl true | ||
def handle_info(:after_join, socket) do | ||
{:ok, _} = | ||
Presence.track(socket, socket.assigns.current_user, %{ | ||
online_at: inspect(System.system_time(:second)), | ||
color: MyButtonApp.Names.getHSL(socket.assigns.current_user) | ||
}) | ||
|
||
push(socket, "presence_state", Presence.list(socket)) | ||
{:noreply, socket} | ||
end | ||
|
||
# Channels can be used in a request/response fashion | ||
# by sending replies to requests from the client | ||
@impl true | ||
def handle_in("ping", payload, socket) do | ||
{:reply, {:ok, payload}, socket} | ||
end | ||
|
||
# It is also common to receive messages from the client and | ||
# broadcast to everyone in the current topic (cursor:lobby). | ||
@impl true | ||
def handle_in("shout", payload, socket) do | ||
broadcast(socket, "shout", payload) | ||
{:noreply, socket} | ||
end | ||
|
||
# Add authorization logic here as required. | ||
defp authorized?(_payload) do | ||
true | ||
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,10 @@ | ||
defmodule MyButtonAppWeb.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: :my_button_app, | ||
pubsub_server: MyButtonApp.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
defmodule MyButtonAppWeb.UserSocket do | ||
use Phoenix.Socket | ||
|
||
# A Socket handler | ||
# | ||
# It's possible to control the websocket connection and | ||
# assign values that can be accessed by your channel topics. | ||
|
||
## Channels | ||
|
||
channel "cursor:*", MyButtonAppWeb.CursorChannel | ||
|
||
# Socket params are passed from the client and can | ||
# be used to verify and authenticate a user. After | ||
# verification, you can put default assigns into | ||
# the socket that will be set for all channels, ie | ||
# | ||
# {:ok, assign(socket, :user_id, verified_user_id)} | ||
# | ||
# To deny connection, return `:error`. | ||
# | ||
# See `Phoenix.Token` documentation for examples in | ||
# performing token verification on connect. | ||
@impl true | ||
def connect(%{"token" => token}, socket, _connect_info) do | ||
# max_age: 1209600 is equivalent to two weeks in seconds | ||
case Phoenix.Token.verify(socket, "user socket", token, max_age: 1_209_600) do | ||
{:ok, user_id} -> | ||
{:ok, assign(socket, :current_user, user_id)} | ||
|
||
{:error, _reason} -> | ||
:error | ||
end | ||
end | ||
|
||
# Socket id's are topics that allow you to identify all sockets for a given user: | ||
# | ||
# def id(socket), do: "user_socket:#{socket.assigns.user_id}" | ||
# | ||
# Would allow you to broadcast a "disconnect" event and terminate | ||
# all active sockets and channels for a given user: | ||
# | ||
# Elixir.MyButtonAppWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) | ||
# | ||
# Returning `nil` makes this socket anonymous. | ||
@impl true | ||
def id(_socket), do: nil | ||
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
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,20 @@ | ||
<section class="flex flex-col w-screen h-screen justify-center items-center text-center"> | ||
<form id="msgform" class="rounded-xl bg-gradient-to-r to-pink-100 from-pink-50 p-8 drop-shadow-xl flex w-xs mx-auto space-x-3"> | ||
<input | ||
class="flex-1 appearance-none border border-transparent py-2 px-4 bg-white text-gray-600 placeholder-gray-400 shadow-md rounded-lg text-base focus:outline-none focus:ring-2 focus:ring-pink-600 focus:border-transparent" | ||
maxlength="30" | ||
aria-label="Your message" | ||
type="text" | ||
id="msg" | ||
name="msg" | ||
placeholder="Say something" | ||
/> | ||
<input | ||
id="submit-name" | ||
type="submit" | ||
class="flex-shrink-0 bg-pink-600 text-white text-base font-semibold py-2 px-4 rounded-lg shadow-md hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-500 focus:ring-offset-2 focus:ring-offset-pink-200" | ||
value="Change" | ||
/> | ||
</form> | ||
<ul id="cursor-list" /> | ||
</section> |
Oops, something went wrong.