Separate active sessions section

Fixes #2562
This commit is contained in:
Pavel Djundik 2020-03-17 17:36:13 +02:00
parent a9d2b30d96
commit a6f70696f3
5 changed files with 54 additions and 32 deletions

View file

@ -7,14 +7,12 @@
session.ip
}}</a>
<template v-if="!session.current">
<p v-if="session.active">
<em>Currently active</em>
</p>
<p v-else>
Last used on <time>{{ lastUse }}</time>
</p>
</template>
<p v-if="session.active > 1" class="session-usage">
Active in {{ session.active }} browsers
</p>
<p v-else-if="!session.current && !session.active" class="session-usage">
Last used on <time>{{ lastUse }}</time>
</p>
</div>
<div class="session-item-btn">
<button class="btn" @click.prevent="signOut">
@ -25,6 +23,28 @@
</div>
</template>
<style>
.session-list .session-item {
display: flex;
font-size: 14px;
}
.session-list .session-item-info {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.session-list .session-item-btn {
flex-shrink: 0;
}
.session-list .session-usage {
font-style: italic;
color: var(--body-color-muted);
}
</style>
<script>
import localetime from "../js/helpers/localetime";
import Auth from "../js/auth";

View file

@ -431,18 +431,24 @@
<h2>Sessions</h2>
<h3>Current session</h3>
<Session
v-if="$store.getters.currentSession"
:session="$store.getters.currentSession"
/>
<Session v-if="currentSession" :session="currentSession" />
<template v-if="activeSessions.length > 0">
<h3>Active sessions</h3>
<Session
v-for="session in activeSessions"
:key="session.token"
:session="session"
/>
</template>
<h3>Other sessions</h3>
<p v-if="$store.state.sessions.length === 0">Loading</p>
<p v-else-if="$store.getters.otherSessions.length === 0">
<p v-else-if="otherSessions.length === 0">
<em>You are not currently logged in to any other device.</em>
</p>
<Session
v-for="session in $store.getters.otherSessions"
v-for="session in otherSessions"
v-else
:key="session.token"
:session="session"
@ -492,6 +498,15 @@ export default {
// TODO: This doesn't hide the button after clicking
return installPromptEvent !== null;
},
currentSession() {
return this.$store.state.sessions.find((item) => item.current);
},
activeSessions() {
return this.$store.state.sessions.filter((item) => !item.current && item.active > 0);
},
otherSessions() {
return this.$store.state.sessions.filter((item) => !item.current && !item.active);
},
},
mounted() {
socket.emit("sessions:get");

View file

@ -399,21 +399,6 @@ p {
#help .documentation-link::before { content: "\f19d"; /* http://fontawesome.io/icon/graduation-cap/ */ }
#help .report-issue-link::before { content: "\f188"; /* http://fontawesome.io/icon/bug/ */ }
.session-list .session-item {
display: flex;
font-size: 14px;
}
.session-list .session-item-info {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.session-list .session-item-btn {
flex-shrink: 0;
}
#chat .msg[data-type="invite"] .from::before {
content: "\f0e0"; /* https://fontawesome.com/icons/envelope?style=solid */
color: #2ecc40;

View file

@ -110,8 +110,6 @@ const store = new Vuex.Store({
},
},
getters: {
currentSession: (state) => state.sessions.find((item) => item.current),
otherSessions: (state) => state.sessions.filter((item) => !item.current),
findChannelOnCurrentNetwork: (state) => (name) => {
name = name.toLowerCase();
return state.activeChannel.network.channels.find((c) => c.name.toLowerCase() === name);

View file

@ -563,7 +563,11 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
const sendSessionList = () => {
const sessions = _.map(client.config.sessions, (session, sessionToken) => ({
current: sessionToken === token,
active: _.find(client.attachedClients, (u) => u.token === sessionToken) !== undefined,
active: _.reduce(
client.attachedClients,
(count, attachedClient) => count + (attachedClient.token === sessionToken ? 1 : 0),
0
),
lastUse: session.lastUse,
ip: session.ip,
agent: session.agent,