Merge pull request #1722 from creesch/contextMenu
Add actions to user context menu
This commit is contained in:
commit
aeb8f66f30
@ -224,6 +224,9 @@ kbd {
|
||||
.context-menu-chan::before { content: "\f292"; /* http://fontawesome.io/icon/hashtag/ */ }
|
||||
.context-menu-close::before { content: "\f00d"; /* http://fontawesome.io/icon/times/ */ }
|
||||
.context-menu-list::before { content: "\f03a"; /* http://fontawesome.io/icon/list/ */ }
|
||||
.context-menu-action-whois::before { content: "\f05a"; /* http://fontawesome.io/icon/info-circle/ */ }
|
||||
.context-menu-action-query::before { content: "\f0e6"; /* http://fontawesome.io/icon/comments-o/ */ }
|
||||
.context-menu-action-kick::before { content: "\f05e"; /* http://fontawesome.io/icon/ban/ */ }
|
||||
|
||||
.context-menu-network::before,
|
||||
#sidebar .chan.lobby::before,
|
||||
|
@ -79,9 +79,34 @@ $(function() {
|
||||
if (target.hasClass("user")) {
|
||||
output = templates.contextmenu_item({
|
||||
class: "user",
|
||||
action: "whois",
|
||||
text: target.text(),
|
||||
data: target.data("name"),
|
||||
});
|
||||
output += templates.contextmenu_divider();
|
||||
output += templates.contextmenu_item({
|
||||
class: "action-whois",
|
||||
action: "whois",
|
||||
text: "User information",
|
||||
data: target.data("name"),
|
||||
});
|
||||
output += templates.contextmenu_item({
|
||||
class: "action-query",
|
||||
action: "query",
|
||||
text: "Direct messages",
|
||||
data: target.data("name"),
|
||||
});
|
||||
|
||||
const channel = target.closest(".chan");
|
||||
if (utils.isOpInChannel(channel) && channel.data("type") === "channel") {
|
||||
output += templates.contextmenu_divider();
|
||||
output += templates.contextmenu_item({
|
||||
class: "action-kick",
|
||||
action: "kick",
|
||||
text: "Kick",
|
||||
data: target.data("name"),
|
||||
});
|
||||
}
|
||||
} else if (target.hasClass("chan")) {
|
||||
let itemClass;
|
||||
|
||||
@ -95,6 +120,7 @@ $(function() {
|
||||
|
||||
output = templates.contextmenu_item({
|
||||
class: itemClass,
|
||||
action: "focusChan",
|
||||
text: target.data("title"),
|
||||
data: target.data("target"),
|
||||
});
|
||||
@ -102,12 +128,14 @@ $(function() {
|
||||
if (target.hasClass("lobby")) {
|
||||
output += templates.contextmenu_item({
|
||||
class: "list",
|
||||
action: "list",
|
||||
text: "List all channels",
|
||||
data: target.data("target"),
|
||||
data: target.data("id"),
|
||||
});
|
||||
}
|
||||
output += templates.contextmenu_item({
|
||||
class: "close",
|
||||
action: "close",
|
||||
text: target.hasClass("lobby") ? "Disconnect" : target.hasClass("channel") ? "Leave" : "Close",
|
||||
data: target.data("target"),
|
||||
});
|
||||
@ -121,7 +149,11 @@ $(function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
viewport.on("contextmenu", ".user, .network .chan", function(e) {
|
||||
viewport.on("contextmenu", ".network .chan", function(e) {
|
||||
return showContextMenu(this, e);
|
||||
});
|
||||
|
||||
viewport.on("click contextmenu", ".user", function(e) {
|
||||
return showContextMenu(this, e);
|
||||
});
|
||||
|
||||
@ -285,20 +317,6 @@ $(function() {
|
||||
$(this).closest(".msg.condensed").toggleClass("closed");
|
||||
});
|
||||
|
||||
chat.on("click", ".user", function() {
|
||||
var name = $(this).data("name");
|
||||
var chan = utils.findCurrentNetworkChan(name);
|
||||
|
||||
if (chan.length) {
|
||||
chan.click();
|
||||
}
|
||||
|
||||
socket.emit("input", {
|
||||
target: chat.data("id"),
|
||||
text: "/whois " + name,
|
||||
});
|
||||
});
|
||||
|
||||
sidebar.on("click", ".chan, button", function(e, data) {
|
||||
// Pushes states to history web API when clicking elements with a data-target attribute.
|
||||
// States are very trivial and only contain a single `clickTarget` property which
|
||||
@ -447,24 +465,60 @@ $(function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
contextMenu.on("click", ".context-menu-item", function() {
|
||||
switch ($(this).data("action")) {
|
||||
case "close":
|
||||
$(".networks .chan[data-target='" + $(this).data("data") + "'] .close").click();
|
||||
break;
|
||||
case "chan":
|
||||
$(".networks .chan[data-target='" + $(this).data("data") + "']").click();
|
||||
break;
|
||||
case "user":
|
||||
$(".channel.active .users .user[data-name='" + $(this).data("data") + "']").click();
|
||||
break;
|
||||
case "list":
|
||||
const contextMenuActions = {
|
||||
close: function(itemData) {
|
||||
$(`.networks .chan[data-target="${itemData}"] .close`).click();
|
||||
},
|
||||
focusChan: function(itemData) {
|
||||
$(`.networks .chan[data-target="${itemData}"]`).click();
|
||||
},
|
||||
list: function(itemData) {
|
||||
socket.emit("input", {
|
||||
target: chat.data("id"),
|
||||
target: itemData,
|
||||
text: "/list",
|
||||
});
|
||||
break;
|
||||
},
|
||||
whois: function(itemData) {
|
||||
const chan = utils.findCurrentNetworkChan(itemData);
|
||||
|
||||
if (chan.length) {
|
||||
chan.click();
|
||||
}
|
||||
|
||||
socket.emit("input", {
|
||||
target: $("#chat").data("id"),
|
||||
text: "/whois " + itemData,
|
||||
});
|
||||
|
||||
$(`.channel.active .users .user[data-name="${itemData}"]`).click();
|
||||
},
|
||||
query: function(itemData) {
|
||||
const chan = utils.findCurrentNetworkChan(itemData);
|
||||
|
||||
if (chan.length) {
|
||||
chan.click();
|
||||
}
|
||||
|
||||
socket.emit("input", {
|
||||
target: $("#chat").data("id"),
|
||||
text: "/query " + itemData,
|
||||
});
|
||||
},
|
||||
kick: function(itemData) {
|
||||
socket.emit("input", {
|
||||
target: $("#chat").data("id"),
|
||||
text: "/kick " + itemData,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
contextMenuActions.execute = (name, ...args) => contextMenuActions[name] && contextMenuActions[name](...args);
|
||||
|
||||
contextMenu.on("click", ".context-menu-item", function() {
|
||||
const $this = $(this);
|
||||
const itemData = $this.data("data");
|
||||
const contextAction = $this.data("action");
|
||||
contextMenuActions.execute(contextAction, itemData);
|
||||
});
|
||||
|
||||
chat.on("input", ".search", function() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const $ = require("jquery");
|
||||
const escape = require("css.escape");
|
||||
const input = $("#input");
|
||||
|
||||
var serverHash = -1;
|
||||
@ -19,6 +20,7 @@ module.exports = {
|
||||
toggleNickEditor,
|
||||
toggleNotificationMarkers,
|
||||
requestIdleCallback,
|
||||
isOpInChannel,
|
||||
};
|
||||
|
||||
function findCurrentNetworkChan(name) {
|
||||
@ -37,6 +39,15 @@ function resetHeight(element) {
|
||||
element.style.height = element.style.minHeight;
|
||||
}
|
||||
|
||||
// Given a channel element will determine if the lounge user is Op in that channel
|
||||
function isOpInChannel(channel) {
|
||||
const channelID = channel.data("id");
|
||||
const network = $("#sidebar .network").has(`.chan[data-id="${channelID}"]`);
|
||||
const ownNick = network.data("nick");
|
||||
const isOP = channel.find(`.users .user-mode.op .user[data-name="${escape(ownNick)}"]`).length;
|
||||
return isOP;
|
||||
}
|
||||
|
||||
// Triggering click event opens the virtual keyboard on mobile
|
||||
// This can only be called from another interactive event (e.g. button click)
|
||||
function forceFocus() {
|
||||
|
@ -1,3 +1,3 @@
|
||||
<li class="context-menu-item context-menu-{{class}}" data-action="{{class}}"{{#if data}} data-data="{{data}}"{{/if}}>
|
||||
<li class="context-menu-item context-menu-{{class}}" data-action="{{action}}"{{#if data}} data-data="{{data}}"{{/if}}>
|
||||
{{text}}
|
||||
</li>
|
||||
|
@ -48,5 +48,6 @@ exports.input = function(network, chan, cmd, args) {
|
||||
this.emit("join", {
|
||||
network: network.id,
|
||||
chan: newChan.getFilteredClone(true),
|
||||
shouldOpen: true,
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user