mirror of
https://github.com/thelounge/thelounge
synced 2024-11-26 14:00:21 +00:00
Port keybinds to vue state; remove jQuery
This commit is contained in:
parent
d0444d7d7f
commit
e76d5d2ef9
5 changed files with 79 additions and 70 deletions
|
@ -1,12 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- TODO: move closed style to it's own class -->
|
<!-- TODO: move closed style to it's own class -->
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="isChannelVisible"
|
||||||
!network.isCollapsed ||
|
|
||||||
channel.highlight ||
|
|
||||||
channel.type === 'lobby' ||
|
|
||||||
(activeChannel && channel === activeChannel.channel)
|
|
||||||
"
|
|
||||||
ref="element"
|
ref="element"
|
||||||
:class="[
|
:class="[
|
||||||
'chan',
|
'chan',
|
||||||
|
@ -33,6 +28,7 @@
|
||||||
<script>
|
<script>
|
||||||
import socket from "../js/socket";
|
import socket from "../js/socket";
|
||||||
import {generateChannelContextMenu} from "../js/helpers/contextMenu.js";
|
import {generateChannelContextMenu} from "../js/helpers/contextMenu.js";
|
||||||
|
import isChannelCollapsed from "../js/helpers/isChannelCollapsed";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ChannelWrapper",
|
name: "ChannelWrapper",
|
||||||
|
@ -49,6 +45,9 @@ export default {
|
||||||
activeChannel() {
|
activeChannel() {
|
||||||
return this.$store.state.activeChannel;
|
return this.$store.state.activeChannel;
|
||||||
},
|
},
|
||||||
|
isChannelVisible() {
|
||||||
|
return !isChannelCollapsed(this.network, this.channel);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
close() {
|
close() {
|
||||||
|
|
15
client/js/helpers/isChannelCollapsed.js
Normal file
15
client/js/helpers/isChannelCollapsed.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import store from "../store";
|
||||||
|
|
||||||
|
export default (network, channel) => {
|
||||||
|
if (!network.isCollapsed || channel.highlight || channel.type === "lobby") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store.state.activeChannel && channel === store.state.activeChannel.channel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
|
@ -2,74 +2,69 @@
|
||||||
|
|
||||||
import Mousetrap from "mousetrap";
|
import Mousetrap from "mousetrap";
|
||||||
|
|
||||||
const $ = require("jquery");
|
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
import {switchToChannel} from "./router";
|
import {switchToChannel} from "./router";
|
||||||
|
import isChannelCollapsed from "./helpers/isChannelCollapsed";
|
||||||
|
|
||||||
// Switch to the next/previous window in the channel list.
|
// Switch to the next/previous window in the channel list.
|
||||||
Mousetrap.bind(["alt+up", "alt+down"], function(e, keys) {
|
Mousetrap.bind(["alt+up", "alt+down"], function(e, keys) {
|
||||||
const sidebar = $("#sidebar");
|
if (store.state.networks.length === 0) {
|
||||||
const channels = sidebar.find(".chan").not(".network.collapsed :not(.lobby)");
|
return false;
|
||||||
const index = channels.index(channels.filter(".active"));
|
|
||||||
const direction = keys.split("+").pop();
|
|
||||||
let target;
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case "up":
|
|
||||||
target = (channels.length + (index - 1 + channels.length)) % channels.length;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "down":
|
|
||||||
target = (channels.length + (index + 1 + channels.length)) % channels.length;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target = channels.eq(target).click();
|
const direction = keys.split("+").pop() === "up" ? -1 : 1;
|
||||||
scrollIntoViewNicely(target[0]);
|
const flatChannels = [];
|
||||||
|
let index = -1;
|
||||||
|
|
||||||
|
for (const network of store.state.networks) {
|
||||||
|
for (const channel of network.channels) {
|
||||||
|
if (isChannelCollapsed(network, channel)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
index === -1 &&
|
||||||
|
store.state.activeChannel &&
|
||||||
|
store.state.activeChannel.channel === channel
|
||||||
|
) {
|
||||||
|
index = flatChannels.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatChannels.push(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Circular array, and a modulo bug workaround because in JS it stays negative
|
||||||
|
const length = flatChannels.length;
|
||||||
|
index = (((index + direction) % length) + length) % length;
|
||||||
|
|
||||||
|
jumpToChannel(flatChannels[index]);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch to the next/previous lobby in the channel list
|
// Switch to the next/previous lobby in the channel list
|
||||||
Mousetrap.bind(["alt+shift+up", "alt+shift+down"], function(e, keys) {
|
Mousetrap.bind(["alt+shift+up", "alt+shift+down"], function(e, keys) {
|
||||||
const sidebar = $("#sidebar");
|
const length = store.state.networks.length;
|
||||||
const lobbies = sidebar.find(".lobby");
|
|
||||||
const direction = keys.split("+").pop();
|
|
||||||
let index = lobbies.index(lobbies.filter(".active"));
|
|
||||||
let target;
|
|
||||||
|
|
||||||
switch (direction) {
|
if (length === 0) {
|
||||||
case "up":
|
return false;
|
||||||
if (index < 0) {
|
|
||||||
target = lobbies.index(
|
|
||||||
sidebar
|
|
||||||
.find(".channel")
|
|
||||||
.filter(".active")
|
|
||||||
.siblings(".lobby")[0]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
target = (lobbies.length + (index - 1 + lobbies.length)) % lobbies.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "down":
|
|
||||||
if (index < 0) {
|
|
||||||
index = lobbies.index(
|
|
||||||
sidebar
|
|
||||||
.find(".channel")
|
|
||||||
.filter(".active")
|
|
||||||
.siblings(".lobby")[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
target = (lobbies.length + (index + 1 + lobbies.length)) % lobbies.length;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target = lobbies.eq(target).click();
|
const direction = keys.split("+").pop() === "up" ? -1 : 1;
|
||||||
scrollIntoViewNicely(target[0]);
|
let index = 0;
|
||||||
|
|
||||||
|
// If we're in another window, jump to first lobby
|
||||||
|
if (store.state.activeChannel) {
|
||||||
|
index = store.state.networks.findIndex((n) => n === store.state.activeChannel.network);
|
||||||
|
|
||||||
|
// If we're in a channel, and it's not the lobby, jump to lobby of this network when going up
|
||||||
|
if (direction !== -1 || store.state.activeChannel.channel.type === "lobby") {
|
||||||
|
index = (((index + direction) % length) + length) % length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jumpToChannel(store.state.networks[index].channels[0]);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -77,28 +72,34 @@ Mousetrap.bind(["alt+shift+up", "alt+shift+down"], function(e, keys) {
|
||||||
// Jump to the first window with a highlight in it, or the first with unread
|
// Jump to the first window with a highlight in it, or the first with unread
|
||||||
// activity if there are none with highlights.
|
// activity if there are none with highlights.
|
||||||
Mousetrap.bind(["alt+a"], function() {
|
Mousetrap.bind(["alt+a"], function() {
|
||||||
let targetchan;
|
let targetChannel;
|
||||||
|
|
||||||
outer_loop: for (const network of store.state.networks) {
|
outer_loop: for (const network of store.state.networks) {
|
||||||
for (const chan of network.channels) {
|
for (const chan of network.channels) {
|
||||||
if (chan.highlight) {
|
if (chan.highlight) {
|
||||||
targetchan = chan;
|
targetChannel = chan;
|
||||||
break outer_loop;
|
break outer_loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan.unread && !targetchan) {
|
if (chan.unread && !targetChannel) {
|
||||||
targetchan = chan;
|
targetChannel = chan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetchan) {
|
if (targetChannel) {
|
||||||
switchToChannel(targetchan);
|
jumpToChannel(targetChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function jumpToChannel(targetChannel) {
|
||||||
|
switchToChannel(targetChannel);
|
||||||
|
|
||||||
|
scrollIntoViewNicely(document.querySelector(`#sidebar .chan[data-id="${targetChannel.id}"]`));
|
||||||
|
}
|
||||||
|
|
||||||
// Ignored keys which should not automatically focus the input bar
|
// Ignored keys which should not automatically focus the input bar
|
||||||
const ignoredKeys = {
|
const ignoredKeys = {
|
||||||
8: true, // Backspace
|
8: true, // Backspace
|
||||||
|
|
|
@ -93,7 +93,6 @@
|
||||||
"graphql-request": "1.8.2",
|
"graphql-request": "1.8.2",
|
||||||
"husky": "3.1.0",
|
"husky": "3.1.0",
|
||||||
"intersection-observer": "0.7.0",
|
"intersection-observer": "0.7.0",
|
||||||
"jquery": "3.4.1",
|
|
||||||
"mini-css-extract-plugin": "0.8.0",
|
"mini-css-extract-plugin": "0.8.0",
|
||||||
"mocha": "6.2.2",
|
"mocha": "6.2.2",
|
||||||
"mochapack": "1.1.11",
|
"mochapack": "1.1.11",
|
||||||
|
|
|
@ -4697,11 +4697,6 @@ istanbul-reports@^2.2.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
handlebars "^4.1.2"
|
handlebars "^4.1.2"
|
||||||
|
|
||||||
jquery@3.4.1:
|
|
||||||
version "3.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
|
|
||||||
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==
|
|
||||||
|
|
||||||
js-levenshtein@^1.1.3:
|
js-levenshtein@^1.1.3:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
|
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
|
||||||
|
|
Loading…
Reference in a new issue