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

View file

@ -265,3 +265,31 @@ export function generateUserContextMenu($root, channel, network, user) {
return items; 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}); navigate("RoutedChat", {id: channel.id});
}, },
closeChannel(channel) { closeChannel(channel) {
if ( if (channel.type === "lobby") {
channel.type === "lobby" && const el = document.querySelector(
// eslint-disable-next-line no-alert `#sidebar .chan[aria-controls="#chan-${channel.id}"]`
!confirm(`Are you sure you want to remove ${channel.name}?`) );
) { const rect = el.getBoundingClientRect();
return false; 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; channel.closed = true;
socket.emit("input", { socket.emit("input", {
target: Number(channel.id), target: Number(channel.id),
text: channel.type === "lobby" ? "/quit" : "/close", text: "/close",
}); });
}, },
}, },