diff --git a/web/channels/system_channel.ex b/web/channels/system_channel.ex index 2a74fd0..06700a1 100644 --- a/web/channels/system_channel.ex +++ b/web/channels/system_channel.ex @@ -1,33 +1,57 @@ defmodule KolabChat.SystemChannel do use KolabChat.Web, :channel alias KolabChat.Presence + @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 {:ok, 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: "online", + status: :online, context: socket.assigns.context }) {:noreply, socket} end def handle_in("set-status", %{"status" => status}, socket) do {:ok, _} = Presence.update(socket, socket.assigns.user.username, %{ - status: status, + status: check_status(status), context: socket.assigns.context }) {:noreply, socket} end + + # Makes sure the provided status name is supported + # Returns status name as an atom + def check_status(status) do + status = String.to_atom(status) + + if Enum.member?(@status, status) do + status + else + :online + end + end end diff --git a/web/static/css/widgets.css b/web/static/css/widgets.css index 923c16e..8e1b3ba 100644 --- a/web/static/css/widgets.css +++ b/web/static/css/widgets.css @@ -1,26 +1,29 @@ /* Style for chat application widgets */ -.status-online .glyphicon-user { +.status-online .glyphicon-user, +.status-away .glyphicon-user { color: green; } -.status-away .glyphicon-user { - color: grey; +.status-busy .glyphicon-user, +.status-unavailable .glyphicon-user { + color: red; } -.status-busy .glyphicon-user { - color: red; +.status-invisible .glyphicon-user, +.status-offline .glyphicon-user { + color: gray; } .userlist .btn-group { float: right; } .textchat { overflow-x: hidden; overflow-y: scroll; } .textchat p { margin: 0; } diff --git a/web/static/js/widgets/userstatus.js b/web/static/js/widgets/userstatus.js index de1e890..6c7d5f9 100644 --- a/web/static/js/widgets/userstatus.js +++ b/web/static/js/widgets/userstatus.js @@ -1,47 +1,63 @@ class UserStatusWidget { /** * Configuration: * - statusChange: handler function for status change */ constructor(id, config) { this.config = config || {} this.id = id + + // FIXME: should we get that list from the backend? + this.status_list = [ + // user is available for chat + "online", + "away", + // user is connected and visible, but not available + "busy", + "unavailable", + // user is shown as offline + "invisible", + "offline" + ]; } /** * Renders user status widget */ render(presence) { let userStatusElement = document.getElementById(this.id) let icon = '' + let options = list => { + return $.map(list, status => + `
  • ${icon} ${status}
  • ` + ).join("\n") + } userStatusElement.innerHTML = ` ` $('.dropdown-menu > li', userStatusElement).click(e => { let status_class = $(e.target).attr('class') if (this.config.statusChange && !$('button > span:first', userStatusElement).hasClass(status_class)) { this.config.statusChange(status_class.replace(/^status-/, '')) } }) } } export default UserStatusWidget