diff --git a/web/channels/system_channel.ex b/web/channels/system_channel.ex --- a/web/channels/system_channel.ex +++ b/web/channels/system_channel.ex @@ -3,34 +3,29 @@ alias KolabChat.Presence - def join("system", _, socket) do - Process.flag(:trap_exit, true) - :timer.send_interval(10000, :ping) + 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 - Presence.track(socket, socket.assigns.user.username, %{ - status: "online" - }) - - push socket, "info", %{user: socket.assigns.user.username} push socket, "presence_state", Presence.list(socket) + push socket, "info", %{user: socket.assigns.user.username} - {:noreply, socket} - end - - def handle_info(:ping, socket) do - push socket, "new:msg", %{user: "SYSTEM", body: "ping"} + Presence.track(socket, socket.assigns.user.username, %{ + 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: status, + context: socket.assigns.context }) {:noreply, socket} diff --git a/web/static/js/api.js b/web/static/js/api.js --- a/web/static/js/api.js +++ b/web/static/js/api.js @@ -10,6 +10,7 @@ /** * Configuration parameters: * - token: User session token + * - context: KolabChat instance identifier * - roomId: Chat room Id to join in * - userListElement: Id of HTML element where to put userslist widget * - userStatusElement: Id of HTML element where to put users status widget @@ -19,6 +20,9 @@ constructor(config) { this.config = config || {} + + if (!this.config.context) + this.config.context = location.hostname; } /** @@ -34,7 +38,7 @@ // TODO: for integration with external systems we'll use configurable full wss:// url this.socket = new Socket("/socket", { - params: {token: this.config.token}, + params: {token: this.config.token, context: this.config.context}, logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }), }) @@ -91,7 +95,7 @@ */ initPresence() { - this.system = this.socket.channel("system") + this.system = this.socket.channel("system", {context: this.config.context}) this.system.on("info", info => { this.username = info.user @@ -146,7 +150,7 @@ let userPresence if (this.userStatusWidget && (userPresence = presences[this.username])) { - userPresence = this.listBy(this.username, userPresence) + userPresence = this.listBy(this.username, userPresence, this.config.context) this.userStatusWidget.render(userPresence) } @@ -156,11 +160,27 @@ } } - listBy(user, {metas: metas}) + listBy(user, {metas: metas}, context) { + let statusWeights = { + offline: 0, + busy: 10, + away: 20, + online: 30 + } + + // Find "best" availability status for the user + // If set, narrow the result to the current session context + let mostAvailableStatus = metas.reduce((best, meta) => { + if (context && context != meta.context) + return best + return statusWeights[best] > statusWeights[meta.status] ? best : meta.status + }, + "offline") + return { user: user, - status: metas[0].status + status: mostAvailableStatus } }