diff --git a/web/channels/system_channel.ex b/web/channels/system_channel.ex index 41b5efb..a520a46 100644 --- a/web/channels/system_channel.ex +++ b/web/channels/system_channel.ex @@ -1,97 +1,105 @@ defmodule KolabChat.SystemChannel do use KolabChat.Web, :channel @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 join("system", %{"context" => context}, socket) do - socket = assign(socket, :context, context) - send self(), :after_join + perform_join(context, socket) + end - {:ok, socket} + def join("system", _args, socket) do + perform_join("default", socket) end def handle_info(:after_join, socket) do push socket, "presence_state", Presence.list(socket) push socket, "info", %{user: socket.assigns.user.username} Presence.track(socket, socket.assigns.user.username, %{ status: get_user_status(socket), context: socket.assigns.context }) {:noreply, socket} end def handle_in("set-status", %{"status" => status}, socket) do status = check_status(status) socket |> update_presence_status(status) |> set_user_status(status) {:noreply, socket} end + defp perform_join(context, socket) do + socket = assign(socket, :context, context) + send self(), :after_join + + {:ok, socket} + end + defp update_presence_status(socket, :invalid), do: socket defp update_presence_status(socket, status) do Presence.update(socket, socket.assigns.user.username, %{ status: status, context: socket.assigns.context }) socket 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 # Get the last user/context status from the database defp get_user_status(socket) do require Amnesia require Amnesia.Helper key = socket.assigns.user.username <> ":" <> 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 defp set_user_status(socket, :invalid), do: socket defp set_user_status(socket, status) do require Amnesia require Amnesia.Helper key = socket.assigns.user.username <> ":" <> socket.assigns.context Amnesia.transaction do Database.Status.write(%Database.Status{key: key, status: status}) end socket end end