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-chan::before { content: "\f292"; /* http://fontawesome.io/icon/hashtag/ */ }
|
||||||
.context-menu-close::before { content: "\f00d"; /* http://fontawesome.io/icon/times/ */ }
|
.context-menu-close::before { content: "\f00d"; /* http://fontawesome.io/icon/times/ */ }
|
||||||
.context-menu-list::before { content: "\f03a"; /* http://fontawesome.io/icon/list/ */ }
|
.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,
|
.context-menu-network::before,
|
||||||
#sidebar .chan.lobby::before,
|
#sidebar .chan.lobby::before,
|
||||||
|
@ -79,9 +79,34 @@ $(function() {
|
|||||||
if (target.hasClass("user")) {
|
if (target.hasClass("user")) {
|
||||||
output = templates.contextmenu_item({
|
output = templates.contextmenu_item({
|
||||||
class: "user",
|
class: "user",
|
||||||
|
action: "whois",
|
||||||
text: target.text(),
|
text: target.text(),
|
||||||
data: target.data("name"),
|
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")) {
|
} else if (target.hasClass("chan")) {
|
||||||
let itemClass;
|
let itemClass;
|
||||||
|
|
||||||
@ -95,6 +120,7 @@ $(function() {
|
|||||||
|
|
||||||
output = templates.contextmenu_item({
|
output = templates.contextmenu_item({
|
||||||
class: itemClass,
|
class: itemClass,
|
||||||
|
action: "focusChan",
|
||||||
text: target.data("title"),
|
text: target.data("title"),
|
||||||
data: target.data("target"),
|
data: target.data("target"),
|
||||||
});
|
});
|
||||||
@ -102,12 +128,14 @@ $(function() {
|
|||||||
if (target.hasClass("lobby")) {
|
if (target.hasClass("lobby")) {
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
class: "list",
|
class: "list",
|
||||||
|
action: "list",
|
||||||
text: "List all channels",
|
text: "List all channels",
|
||||||
data: target.data("target"),
|
data: target.data("id"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
class: "close",
|
class: "close",
|
||||||
|
action: "close",
|
||||||
text: target.hasClass("lobby") ? "Disconnect" : target.hasClass("channel") ? "Leave" : "Close",
|
text: target.hasClass("lobby") ? "Disconnect" : target.hasClass("channel") ? "Leave" : "Close",
|
||||||
data: target.data("target"),
|
data: target.data("target"),
|
||||||
});
|
});
|
||||||
@ -121,7 +149,11 @@ $(function() {
|
|||||||
return false;
|
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);
|
return showContextMenu(this, e);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -285,20 +317,6 @@ $(function() {
|
|||||||
$(this).closest(".msg.condensed").toggleClass("closed");
|
$(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) {
|
sidebar.on("click", ".chan, button", function(e, data) {
|
||||||
// Pushes states to history web API when clicking elements with a data-target attribute.
|
// 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
|
// States are very trivial and only contain a single `clickTarget` property which
|
||||||
@ -447,24 +465,60 @@ $(function() {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
contextMenu.on("click", ".context-menu-item", function() {
|
const contextMenuActions = {
|
||||||
switch ($(this).data("action")) {
|
close: function(itemData) {
|
||||||
case "close":
|
$(`.networks .chan[data-target="${itemData}"] .close`).click();
|
||||||
$(".networks .chan[data-target='" + $(this).data("data") + "'] .close").click();
|
},
|
||||||
break;
|
focusChan: function(itemData) {
|
||||||
case "chan":
|
$(`.networks .chan[data-target="${itemData}"]`).click();
|
||||||
$(".networks .chan[data-target='" + $(this).data("data") + "']").click();
|
},
|
||||||
break;
|
list: function(itemData) {
|
||||||
case "user":
|
|
||||||
$(".channel.active .users .user[data-name='" + $(this).data("data") + "']").click();
|
|
||||||
break;
|
|
||||||
case "list":
|
|
||||||
socket.emit("input", {
|
socket.emit("input", {
|
||||||
target: chat.data("id"),
|
target: itemData,
|
||||||
text: "/list",
|
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() {
|
chat.on("input", ".search", function() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
|
const escape = require("css.escape");
|
||||||
const input = $("#input");
|
const input = $("#input");
|
||||||
|
|
||||||
var serverHash = -1;
|
var serverHash = -1;
|
||||||
@ -19,6 +20,7 @@ module.exports = {
|
|||||||
toggleNickEditor,
|
toggleNickEditor,
|
||||||
toggleNotificationMarkers,
|
toggleNotificationMarkers,
|
||||||
requestIdleCallback,
|
requestIdleCallback,
|
||||||
|
isOpInChannel,
|
||||||
};
|
};
|
||||||
|
|
||||||
function findCurrentNetworkChan(name) {
|
function findCurrentNetworkChan(name) {
|
||||||
@ -37,6 +39,15 @@ function resetHeight(element) {
|
|||||||
element.style.height = element.style.minHeight;
|
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
|
// Triggering click event opens the virtual keyboard on mobile
|
||||||
// This can only be called from another interactive event (e.g. button click)
|
// This can only be called from another interactive event (e.g. button click)
|
||||||
function forceFocus() {
|
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}}
|
{{text}}
|
||||||
</li>
|
</li>
|
||||||
|
@ -48,5 +48,6 @@ exports.input = function(network, chan, cmd, args) {
|
|||||||
this.emit("join", {
|
this.emit("join", {
|
||||||
network: network.id,
|
network: network.id,
|
||||||
chan: newChan.getFilteredClone(true),
|
chan: newChan.getFilteredClone(true),
|
||||||
|
shouldOpen: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user