Changeset View
Changeset View
Standalone View
Standalone View
web/channels/system_channel.ex
defmodule KolabChat.SystemChannel do | defmodule KolabChat.SystemChannel do | ||||
use KolabChat.Web, :channel | use KolabChat.Web, :channel | ||||
alias KolabChat.Presence | alias KolabChat.Presence | ||||
def join("system", _, socket) do | @status [ | ||||
Process.flag(:trap_exit, true) | # user is available for chat | ||||
:timer.send_interval(10000, :ping) | :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 | |||||
seigo: this fails if no context is provided. imho this should be an optional parameter. see attached… | |||||
socket = assign(socket, :context, context) | |||||
send self(), :after_join | send self(), :after_join | ||||
{:ok, socket} | {:ok, socket} | ||||
end | end | ||||
def handle_info(:after_join, socket) do | 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, %{ | Presence.track(socket, socket.assigns.user.username, %{ | ||||
status: "online" | status: :online, | ||||
context: socket.assigns.context | |||||
}) | }) | ||||
push socket, "info", %{user: socket.assigns.user.username} | |||||
push socket, "presence_state", Presence.list(socket) | |||||
{:noreply, socket} | {:noreply, socket} | ||||
end | end | ||||
def handle_info(:ping, socket) do | def handle_in("set-status", %{"status" => status}, socket) do | ||||
push socket, "new:msg", %{user: "SYSTEM", body: "ping"} | update_presence_status(check_status(status), socket) | ||||
{:noreply, socket} | {:noreply, socket} | ||||
end | end | ||||
def handle_in("set-status", %{"status" => status}, socket) do | defp update_presence_status(:invalid, _socket), do: :ok | ||||
defp update_presence_status(status, socket) do | |||||
{:ok, _} = Presence.update(socket, socket.assigns.user.username, %{ | {:ok, _} = Presence.update(socket, socket.assigns.user.username, %{ | ||||
status: status | status: status, | ||||
context: socket.assigns.context | |||||
Not Done Inline ActionsJust to add to my comment from yesterday... to keep this simple and performant, this could perhaps be: update_presence_status(check_status(status, socket)) with: defp update_presence_status(:invalid_status, _socket), do: :ok defp update_presence_status(new_status, socket) do: {:ok, _} = Presence.update(socket, socket.assigns.user.username, %{ status: new_status, context: socket.assigns.context }) end and then check_status can return :invalid_status when the status is .. well .. not valid :) seigo: Just to add to my comment from yesterday... to keep this simple and performant, this could… | |||||
}) | }) | ||||
end | |||||
{:noreply, socket} | # 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 | end | ||||
Not Done Inline ActionsShould this return the existing status rather than online? What if the user is busy and then tries to switch to sth invalid.. this would make them online rather than keep busy, no? seigo: Should this return the existing status rather than online? What if the user is busy and then… |
this fails if no context is provided. imho this should be an optional parameter. see attached patch: