Replace confirm() with context menu

window.confirm() blocks the javascript thread and will cause the socket connection to drop
This commit is contained in:
Pavel Djundik 2019-11-23 21:53:33 +02:00
parent 9b9c547e8c
commit 90ec37ce82
3 changed files with 61 additions and 12 deletions

View file

@ -35,7 +35,11 @@
<script>
import Mousetrap from "mousetrap";
import {generateUserContextMenu, generateChannelContextMenu} from "../js/helpers/contextMenu.js";
import {
generateUserContextMenu,
generateChannelContextMenu,
generateRemoveNetwork,
} from "../js/helpers/contextMenu.js";
export default {
name: "ContextMenu",
@ -60,6 +64,7 @@ export default {
this.$root.$on("contextmenu:user", this.openUserContextMenu);
this.$root.$on("contextmenu:channel", this.openChannelContextMenu);
this.$root.$on("contextmenu:removenetwork", this.openRemoveNetworkContextMenu);
},
destroyed() {
Mousetrap.unbind("esc", this.close);
@ -67,8 +72,13 @@ export default {
this.$root.$off("contextmenu:user", this.openUserContextMenu);
this.$root.$off("contextmenu:channel", this.openChannelContextMenu);
this.$root.$off("contextmenu:removenetwork", this.openRemoveNetworkContextMenu);
},
methods: {
openRemoveNetworkContextMenu(data) {
const items = generateRemoveNetwork(this.$root, data.lobby);
this.open(data.event, items);
},
openChannelContextMenu(data) {
const items = generateChannelContextMenu(this.$root, data.channel, data.network);
this.open(data.event, items);
@ -117,12 +127,12 @@ export default {
this.activeItem = id;
},
clickItem(item) {
this.close();
if (item.action) {
item.action();
this.close();
} else if (item.link) {
this.$router.push(item.link);
this.close();
}
},
clickActiveItem() {
@ -142,7 +152,7 @@ export default {
const nextItem = this.items[currentIndex];
// If the next item we would select is a divider, skip over it
if (nextItem && !nextItem.action && !nextItem.link) {
if (nextItem && nextItem.type === "divider") {
currentIndex += direction;
}
@ -166,7 +176,7 @@ export default {
const menuWidth = this.$refs.contextMenu.offsetWidth;
const menuHeight = this.$refs.contextMenu.offsetHeight;
if (element.classList.contains("menu")) {
if (element && element.classList.contains("menu")) {
return {
left: element.getBoundingClientRect().left - (menuWidth - element.offsetWidth),
top: element.getBoundingClientRect().top + element.offsetHeight,

View file

@ -265,3 +265,31 @@ export function generateUserContextMenu($root, channel, network, user) {
return items;
}
export function generateRemoveNetwork($root, lobby) {
return [
{
label: lobby.name,
type: "item",
class: "network",
},
{
type: "divider",
},
{
label: "Yes, remove this",
type: "item",
action() {
lobby.closed = true;
socket.emit("input", {
target: Number(lobby.id),
text: "/quit",
});
},
},
{
label: "Cancel",
type: "item",
},
];
}

View file

@ -30,19 +30,30 @@ const vueApp = new Vue({
navigate("RoutedChat", {id: channel.id});
},
closeChannel(channel) {
if (
channel.type === "lobby" &&
// eslint-disable-next-line no-alert
!confirm(`Are you sure you want to remove ${channel.name}?`)
) {
return false;
if (channel.type === "lobby") {
const el = document.querySelector(
`#sidebar .chan[aria-controls="#chan-${channel.id}"]`
);
const rect = el.getBoundingClientRect();
const event = new MouseEvent("click", {
view: window,
clientX: rect.x + 10,
clientY: rect.y,
});
this.$root.$emit("contextmenu:removenetwork", {
event: event,
lobby: channel,
});
return;
}
channel.closed = true;
socket.emit("input", {
target: Number(channel.id),
text: channel.type === "lobby" ? "/quit" : "/close",
text: "/close",
});
},
},