Implement network collapsing in Vue

This commit is contained in:
Pavel Djundik 2018-07-08 23:08:08 +03:00 committed by Pavel Djundik
parent e0e48925b5
commit dee76adc0c
8 changed files with 40 additions and 57 deletions

View file

@ -1,13 +1,14 @@
<template>
<div
v-if="!network.isCollapsed || channel.highlight || channel.type === 'lobby'"
:key="channel.id"
:class="[ channel.type, { active: activeChannel && channel.id === activeChannel.channel.id } ]"
:class="[ channel.type, { active: activeChannel && channel === activeChannel.channel } ]"
:aria-label="channel.name"
:title="channel.name"
:data-id="channel.id"
:data-target="'#chan-' + channel.id"
:aria-controls="'#chan-' + channel.id"
:aria-selected="activeChannel && channel.id === activeChannel.channel.id"
:aria-selected="activeChannel && channel === activeChannel.channel"
class="chan"
role="tab"
>
@ -15,9 +16,10 @@
<button
v-if="network.channels.length > 1"
:aria-controls="'network-' + network.uuid"
:aria-label="getExpandLabel(network)"
:aria-expanded="!network.isCollapsed"
class="collapse-network"
aria-label="Collapse"
aria-expanded="true"
@click.prevent="onCollapseClick"
>
<span class="collapse-network-icon"/>
</button>
@ -84,6 +86,8 @@
</template>
<script>
const storage = require("../js/localStorage");
export default {
name: "Channel",
props: {
@ -91,5 +95,22 @@ export default {
network: Object,
channel: Object,
},
methods: {
onCollapseClick() {
const networks = new Set(JSON.parse(storage.get("thelounge.networks.collapsed")));
this.network.isCollapsed = !this.network.isCollapsed;
if (this.network.isCollapsed) {
networks.add(this.network.uuid);
} else {
networks.delete(this.network.uuid);
}
storage.set("thelounge.networks.collapsed", JSON.stringify([...networks]));
},
getExpandLabel(network) {
return network.isCollapsed ? "Expand" : "Collapse";
},
},
};
</script>

View file

@ -3,11 +3,11 @@
<div class="count">
<input
:placeholder="channel.users.length + ' user' + (channel.users.length === 1 ? '' : 's')"
v-model="userSearchInput"
type="search"
class="search"
aria-label="Search among the user list"
tabindex="-1"
v-model="userSearchInput"
>
</div>
<div class="names">
@ -57,7 +57,7 @@ export default {
props: {
channel: Object,
},
data: function() {
data() {
return {
userSearchInput: "",
};
@ -101,9 +101,6 @@ export default {
getModeClass(mode) {
return modes[mode];
},
onInput(e) {
console.log(this.channel.userSearchInput);
},
},
};
</script>

View file

@ -16,7 +16,11 @@
<div
v-for="network in networks"
:key="network.uuid"
:class="{ 'not-connected': !network.status.connected, 'not-secure': !network.status.secure }"
:class="{
collapsed: network.isCollapsed,
'not-connected': !network.status.connected,
'not-secure': !network.status.secure,
}"
:id="'network-' + network.uuid"
:data-uuid="network.uuid"
:data-nick="network.nick"

View file

@ -2,7 +2,8 @@
<span
:class="['user', $options.filters.colorClass(user.original.nick)]"
:data-name="user.original.nick"
role="button" v-html="user.original.mode + user.string"/>
role="button"
v-html="user.original.mode + user.string"/>
</template>
<script>

View file

@ -563,10 +563,6 @@ kbd {
font-size: 14px;
}
#sidebar .network.collapsed .chan:not(.lobby) {
display: none;
}
#sidebar .chan {
cursor: pointer;
}

View file

@ -8,9 +8,7 @@ const utils = require("./utils");
const constants = require("./constants");
const condensed = require("./condensed");
const JoinChannel = require("./join-channel");
const storage = require("./localStorage");
const {vueApp} = require("./vue");
const sidebar = $("#sidebar");
module.exports = {
renderNetworks,
@ -113,17 +111,11 @@ function buildChatMessage(msg) {
}
function renderNetworks(data, singleNetwork) {
const collapsed = new Set(JSON.parse(storage.get("thelounge.networks.collapsed")));
// Add keyboard handlers to the "Join a channel…" form inputs/button
JoinChannel.handleKeybinds(data.networks);
let newChannels;
const channels = $.map(data.networks, function(n) {
if (collapsed.has(n.uuid)) {
collapseNetwork($(`.network[data-uuid="${n.uuid}"] button.collapse-network`));
}
return n.channels;
});
@ -194,32 +186,3 @@ function trimMessageInChannel(channel, messageLimit) {
}
});
}
sidebar.on("click", "button.collapse-network", (e) => collapseNetwork($(e.target)));
function collapseNetwork(target) {
const collapseButton = target.closest(".collapse-network");
const networks = new Set(JSON.parse(storage.get("thelounge.networks.collapsed")));
const networkuuid = collapseButton.closest(".network").data("uuid");
if (collapseButton.closest(".network").find(".active").length > 0) {
collapseButton.closest(".lobby").trigger("click", {
keepSidebarOpen: true,
});
}
collapseButton.closest(".network").toggleClass("collapsed");
if (collapseButton.attr("aria-expanded") === "true") {
collapseButton.attr("aria-expanded", false);
collapseButton.attr("aria-label", "Expand");
networks.add(networkuuid);
} else {
collapseButton.attr("aria-expanded", true);
collapseButton.attr("aria-label", "Collapse");
networks.delete(networkuuid);
}
storage.set("thelounge.networks.collapsed", JSON.stringify([...networks]));
return false;
}

View file

@ -21,6 +21,12 @@ socket.on("init", function(data) {
previousActive = sidebar.find(".active").data("id");
}
const networks = new Set(JSON.parse(storage.get("thelounge.networks.collapsed")));
for (const network of data.networks) {
network.isCollapsed = networks.has(network.uuid);
}
vueApp.networks = data.networks;
if (data.networks.length > 0) {

View file

@ -1,5 +0,0 @@
<div class="user-mode user-mode-search">
{{#each matches}}
<span role="button" class="{{original.className}}" data-name="{{original.dataset.name}}">{{{string}}}</span>
{{/each}}
</div>