From d7e6db92b594a179fd2184e859d69011b0871dc6 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Tue, 15 Aug 2017 12:44:29 +0300 Subject: [PATCH] Implement session list --- client/css/style.css | 9 +++++ client/index.html | 19 +++++++--- client/js/lounge.js | 8 ++++- client/js/socket-events/index.js | 1 + client/js/socket-events/sessions_list.js | 31 +++++++++++++++++ client/views/index.js | 1 + client/views/session.tpl | 17 +++++++++ src/server.js | 44 ++++++++++++++++++++++-- 8 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 client/js/socket-events/sessions_list.js create mode 100644 client/views/session.tpl diff --git a/client/css/style.css b/client/css/style.css index aaed0a37..807aae85 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -252,6 +252,14 @@ kbd { color: #7f8c8d; } +.session-list strong { + display: block; +} + +.session-list p { + margin-bottom: 10px; +} + #chat .invite .from::before { content: "\f003"; /* http://fontawesome.io/icon/envelope-o/ */ color: #2ecc40; @@ -668,6 +676,7 @@ kbd { width: 100%; } +#windows p, #windows label, #settings .error { font-size: 14px; diff --git a/client/index.html b/client/index.html index 5b170e63..26f4c4f4 100644 --- a/client/index.html +++ b/client/index.html @@ -198,15 +198,14 @@ -
+
+

Settings

+
-
-

Settings

-

Messages

@@ -380,6 +379,18 @@
+ + {{#unless public}} +
+

Sessions

+ +

Current session

+
+ +

Other sessions

+
+
+ {{/unless}}
diff --git a/client/js/lounge.js b/client/js/lounge.js index 009871bb..9daad56b 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -383,8 +383,9 @@ $(function() { } document.title = title; + const type = chan.data("type"); var placeholder = ""; - if (chan.data("type") === "channel" || chan.data("type") === "query") { + if (type === "channel" || type === "query") { placeholder = `Write to ${chan.data("title")}`; } input.attr("placeholder", placeholder); @@ -404,6 +405,11 @@ $(function() { socket.emit("names", {target: self.data("id")}); } + if (type === "settings") { + $("#session-list").html("

Loading…

"); + socket.emit("sessions:get"); + } + focus(); }); diff --git a/client/js/socket-events/index.js b/client/js/socket-events/index.js index 23a5e961..b0064665 100644 --- a/client/js/socket-events/index.js +++ b/client/js/socket-events/index.js @@ -17,3 +17,4 @@ require("./sync_sort"); require("./topic"); require("./users"); require("./sign_out"); +require("./sessions_list"); diff --git a/client/js/socket-events/sessions_list.js b/client/js/socket-events/sessions_list.js new file mode 100644 index 00000000..9d77df46 --- /dev/null +++ b/client/js/socket-events/sessions_list.js @@ -0,0 +1,31 @@ +"use strict"; + +const $ = require("jquery"); +const socket = require("../socket"); +const templates = require("../../views"); + +socket.on("sessions:list", function(data) { + data.sort((a, b) => b.lastUse - a.lastUse); + + let html = ""; + data.forEach((connection) => { + if (connection.current) { + $("#session-current").html(templates.session(connection)); + return; + } + + html += templates.session(connection); + }); + + if (html.length === 0) { + html = "

You are not currently logged in to any other device.

"; + } + + $("#session-list").html(html); +}); + +$("#settings").on("click", ".remove-session", function() { + socket.emit("sign-out", $(this).data("token")); + + return false; +}); diff --git a/client/views/index.js b/client/views/index.js index 50f6a93f..118fa60c 100644 --- a/client/views/index.js +++ b/client/views/index.js @@ -34,6 +34,7 @@ module.exports = { msg_unhandled: require("./msg_unhandled.tpl"), network: require("./network.tpl"), image_viewer: require("./image_viewer.tpl"), + session: require("./session.tpl"), unread_marker: require("./unread_marker.tpl"), user: require("./user.tpl"), user_filtered: require("./user_filtered.tpl"), diff --git a/client/views/session.tpl b/client/views/session.tpl new file mode 100644 index 00000000..d3d5cbd8 --- /dev/null +++ b/client/views/session.tpl @@ -0,0 +1,17 @@ +

+{{#if current}} + {{agent}} + {{ip}} +{{else}} + + + {{agent}} + {{ip}} +
+ {{#if active}} + Currently active + {{else}} + Last used on + {{/if}} +{{/if}} +

diff --git a/src/server.js b/src/server.js index e43cc70b..a5f58d3a 100644 --- a/src/server.js +++ b/src/server.js @@ -378,8 +378,32 @@ function initializeClient(socket, client, token, lastMessage) { client.unregisterPushSubscription(token); }); - socket.on("sign-out", () => { - delete client.config.sessions[token]; + const sendSessionList = () => { + const sessions = _.map(client.config.sessions, (session, sessionToken) => ({ + current: sessionToken === token, + active: _.find(client.attachedClients, (u) => u.token === sessionToken) !== undefined, + lastUse: session.lastUse, + ip: session.ip, + agent: session.agent, + token: sessionToken, // TODO: Ideally don't expose actual tokens to the client + })); + + socket.emit("sessions:list", sessions); + }; + + socket.on("sessions:get", sendSessionList); + + socket.on("sign-out", (tokenToSignOut) => { + // If no token provided, sign same client out + if (!tokenToSignOut) { + tokenToSignOut = token; + } + + if (!(tokenToSignOut in client.config.sessions)) { + return; + } + + delete client.config.sessions[tokenToSignOut]; client.manager.updateUser(client.name, { sessions: client.config.sessions @@ -389,7 +413,21 @@ function initializeClient(socket, client, token, lastMessage) { } }); - socket.emit("sign-out"); + _.map(client.attachedClients, (attachedClient, socketId) => { + if (attachedClient.token !== tokenToSignOut) { + return; + } + + const socketToRemove = manager.sockets.of("/").connected[socketId]; + + socketToRemove.emit("sign-out"); + socketToRemove.disconnect(); + }); + + // Do not send updated session list if user simply logs out + if (tokenToSignOut !== token) { + sendSessionList(); + } }); socket.join(client.id);