Skip to content

Commit

Permalink
feat: Adding basic Presence for list of logged in users. #14
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed Feb 13, 2023
1 parent e10e8dc commit 0ec176e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
9 changes: 9 additions & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ channel.on('shout', function (payload) {
render_message(payload)
});

// Listening to presence events
channel.on('presence_diff', function (payload) {
console.log(payload)
});

channel.on('presence_state', function (payload) {
console.log(payload)
});


// Send the message to the server on "shout" channel
function sendMessage() {
Expand Down
1 change: 1 addition & 0 deletions lib/chat/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ defmodule Chat.Application do
Chat.Repo,
# Start the PubSub system
{Phoenix.PubSub, name: Chat.PubSub},
ChatWeb.Presence,
# Start the Endpoint (http/https)
ChatWeb.Endpoint
# Start a worker by calling: Chat.Worker.start_link(arg)
Expand Down
38 changes: 33 additions & 5 deletions lib/chat_web/channels/room_channel.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule ChatWeb.RoomChannel do
use ChatWeb, :channel
alias ChatWeb.Presence

@impl true
def join("room:lobby", payload, socket) do
Expand All @@ -22,16 +23,23 @@ defmodule ChatWeb.RoomChannel do
# broadcast to everyone in the current topic (room:lobby).
@impl true
def handle_in("shout", payload, socket) do
Chat.Message.changeset(%Chat.Message{}, payload) |> Chat.Repo.insert()
broadcast(socket, "shout", payload)
# Insert message in database
{:ok, msg} = Chat.Message.changeset(%Chat.Message{}, payload) |> Chat.Repo.insert()

# Assigning username to socket assigns and tracking presence
socket
|> assign(:user_name, msg.name)
|> track_presence()
|> broadcast("shout", Map.put_new(payload, :id, msg.id))

{:noreply, socket}
end

@impl true
def handle_info(:after_join, socket) do
# Get messages and list them
Chat.Message.get_messages()
# revers to display the latest message at the bottom of the page
|> Enum.reverse()
|> Enum.reverse() # reverts the enum to display the latest message at the bottom of the page
|> Enum.each(fn msg ->
push(socket, "shout", %{
name: msg.name,
Expand All @@ -40,12 +48,32 @@ defmodule ChatWeb.RoomChannel do
})
end)

# :noreply
# Send currently online users in lobby
push(socket, "presence_state", Presence.list("room:lobby"))

{:noreply, socket}
end

# Add authorization logic here as required.
defp authorized?(_payload) do
true
end


# Add a track in Presence when user joins the channel
# Ideally this should be on joining "room:lobby" but the socket has no info as of now
# to associate with a user.

defp track_presence(socket) do
case do_track(socket) do
{:ok, _ref} -> socket
{:error, {:already_tracked, _pid, _channel, _user}} -> socket
end
end

defp do_track(%{assigns: %{user_name: user_name}} = socket) when not is_nil(user_name) do
Presence.track(socket, user_name, %{
online_at: inspect(System.system_time(:second))
})
end
end
5 changes: 5 additions & 0 deletions lib/chat_web/presence.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule ChatWeb.Presence do
use Phoenix.Presence,
otp_app: :chat,
pubsub_server: Chat.PubSub
end

0 comments on commit 0ec176e

Please sign in to comment.