Changeset View
Changeset View
Standalone View
Standalone View
lib/kolab_chat/web/channels/presence.ex
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | defmodule KolabChat.Web.Presence do | ||||
The function above fetches all users from the database who | The function above fetches all users from the database who | ||||
have registered presences for the given topic. The fetched | have registered presences for the given topic. The fetched | ||||
information is then extended with a `:user` key of the user's | information is then extended with a `:user` key of the user's | ||||
information, while maintaining the required `:metas` field from the | information, while maintaining the required `:metas` field from the | ||||
original presence data. | original presence data. | ||||
""" | """ | ||||
use Phoenix.Presence, otp_app: :kolab_chat, | use Phoenix.Presence, otp_app: :kolab_chat, | ||||
pubsub_server: KolabChat.PubSub | pubsub_server: KolabChat.PubSub | ||||
require Amnesia | |||||
require Amnesia.Helper | |||||
alias KolabChat.Database | |||||
@status [ | |||||
# user is available for chat | |||||
:online, | |||||
:away, | |||||
# user is connected and visible, but not available | |||||
:busy, | |||||
:unavailable, | |||||
# user is shown as offline | |||||
:invisible, | |||||
:offline | |||||
] | |||||
def track_presence(socket) do | |||||
track(socket, socket.assigns.user.id, %{ | |||||
username: socket.assigns.user.username, | |||||
status: get_status(socket), | |||||
context: socket.assigns.context | |||||
}) | |||||
end | |||||
def update_status(socket, status) do | |||||
case check_status(status) do | |||||
:invalid -> | |||||
socket | |||||
status -> | |||||
update(socket, socket.assigns.user.id, %{ | |||||
username: socket.assigns.user.username, | |||||
status: status, | |||||
context: socket.assigns.context | |||||
}) | |||||
socket | |||||
end | |||||
end | |||||
# Get the last user/context status from the database | |||||
def get_status(socket) do | |||||
key = Integer.to_string(socket.assigns.user.id) <> ":" <> socket.assigns.context | |||||
Amnesia.transaction do | |||||
case Database.Status.read(key) do | |||||
# use last status | |||||
%Database.Status{status: status} -> status | |||||
# otherwise set status to online | |||||
_ -> :online | |||||
end | |||||
end | |||||
end | |||||
# Save the current user/context status to the database | |||||
def set_status(socket, status) do | |||||
case check_status(status) do | |||||
:invalid -> | |||||
socket | |||||
status -> | |||||
key = Integer.to_string(socket.assigns.user.id) <> ":" <> socket.assigns.context | |||||
Amnesia.transaction do | |||||
Database.Status.write(%Database.Status{key: key, status: status}) | |||||
end | |||||
socket | |||||
end | |||||
end | |||||
# Makes sure the provided status name is supported | |||||
# Returns status name as an atom | |||||
defp check_status(status) do | |||||
status = String.to_atom(status) | |||||
if Enum.member?(@status, status) do | |||||
status | |||||
else | |||||
:invalid | |||||
end | |||||
end | |||||
end | end |