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> <template>
<div <div
v-if="!network.isCollapsed || channel.highlight || channel.type === 'lobby'"
:key="channel.id" :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" :aria-label="channel.name"
:title="channel.name" :title="channel.name"
:data-id="channel.id" :data-id="channel.id"
:data-target="'#chan-' + channel.id" :data-target="'#chan-' + channel.id"
:aria-controls="'#chan-' + channel.id" :aria-controls="'#chan-' + channel.id"
:aria-selected="activeChannel && channel.id === activeChannel.channel.id" :aria-selected="activeChannel && channel === activeChannel.channel"
class="chan" class="chan"
role="tab" role="tab"
> >
@ -15,9 +16,10 @@
<button <button
v-if="network.channels.length > 1" v-if="network.channels.length > 1"
:aria-controls="'network-' + network.uuid" :aria-controls="'network-' + network.uuid"
:aria-label="getExpandLabel(network)"
:aria-expanded="!network.isCollapsed"
class="collapse-network" class="collapse-network"
aria-label="Collapse" @click.prevent="onCollapseClick"
aria-expanded="true"
> >
<span class="collapse-network-icon"/> <span class="collapse-network-icon"/>
</button> </button>
@ -84,6 +86,8 @@
</template> </template>
<script> <script>
const storage = require("../js/localStorage");
export default { export default {
name: "Channel", name: "Channel",
props: { props: {
@ -91,5 +95,22 @@ export default {
network: Object, network: Object,
channel: 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> </script>

View file

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

View file

@ -16,7 +16,11 @@
<div <div
v-for="network in networks" v-for="network in networks"
:key="network.uuid" :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" :id="'network-' + network.uuid"
:data-uuid="network.uuid" :data-uuid="network.uuid"
:data-nick="network.nick" :data-nick="network.nick"

View file

@ -2,7 +2,8 @@
<span <span
:class="['user', $options.filters.colorClass(user.original.nick)]" :class="['user', $options.filters.colorClass(user.original.nick)]"
:data-name="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> </template>
<script> <script>

View file

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

View file

@ -8,9 +8,7 @@ const utils = require("./utils");
const constants = require("./constants"); const constants = require("./constants");
const condensed = require("./condensed"); const condensed = require("./condensed");
const JoinChannel = require("./join-channel"); const JoinChannel = require("./join-channel");
const storage = require("./localStorage");
const {vueApp} = require("./vue"); const {vueApp} = require("./vue");
const sidebar = $("#sidebar");
module.exports = { module.exports = {
renderNetworks, renderNetworks,
@ -113,17 +111,11 @@ function buildChatMessage(msg) {
} }
function renderNetworks(data, singleNetwork) { 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 // Add keyboard handlers to the "Join a channel…" form inputs/button
JoinChannel.handleKeybinds(data.networks); JoinChannel.handleKeybinds(data.networks);
let newChannels; let newChannels;
const channels = $.map(data.networks, function(n) { const channels = $.map(data.networks, function(n) {
if (collapsed.has(n.uuid)) {
collapseNetwork($(`.network[data-uuid="${n.uuid}"] button.collapse-network`));
}
return n.channels; 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"); 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; vueApp.networks = data.networks;
if (data.networks.length > 0) { 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>