add 'op' and 'voice' context menu entries

This commit is contained in:
Jay2k1 2018-04-13 17:53:41 +02:00 committed by Jay2k1
parent 81188e8ef6
commit 808b2b249b
3 changed files with 87 additions and 5 deletions

View file

@ -279,6 +279,8 @@ kbd {
.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-whois::before { content: "\f05a"; /* http://fontawesome.io/icon/info-circle/ */ }
.context-menu-action-kick::before { content: "\f05e"; /* http://fontawesome.io/icon/ban/ */ } .context-menu-action-kick::before { content: "\f05e"; /* http://fontawesome.io/icon/ban/ */ }
.context-menu-action-op::before { content: "\f1fa"; /* http://fontawesome.io/icon/at/ */ }
.context-menu-action-voice::before { content: "\f067"; /* http://fontawesome.io/icon/plus/ */ }
.context-menu-network::before { content: "\f233"; /* https://fontawesome.com/icons/server?style=solid */ } .context-menu-network::before { content: "\f233"; /* https://fontawesome.com/icons/server?style=solid */ }
#sidebar .not-secure-icon::before { #sidebar .not-secure-icon::before {
@ -1952,7 +1954,7 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
min-width: 160px; min-width: 180px;
font-size: 14px; font-size: 14px;
background-color: #fff; background-color: #fff;
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15);

View file

@ -125,6 +125,82 @@ function addKickItem() {
}); });
} }
function addOpItem() {
function op(itemData) {
socket.emit("input", {
target: $("#chat").data("id"),
text: "/op " + itemData,
});
}
addContextMenuItem({
check: (target) =>
utils.hasRoleInChannel(target.closest(".chan"), ["op"]) &&
!utils.hasRoleInChannel(target.closest(".chan"), ["op"], target.data("name")),
className: "action-op",
displayName: "Give operator (+o)",
data: (target) => target.data("name"),
callback: op,
});
}
function addDeopItem() {
function deop(itemData) {
socket.emit("input", {
target: $("#chat").data("id"),
text: "/deop " + itemData,
});
}
addContextMenuItem({
check: (target) =>
utils.hasRoleInChannel(target.closest(".chan"), ["op"]) &&
utils.hasRoleInChannel(target.closest(".chan"), ["op"], target.data("name")),
className: "action-op",
displayName: "Revoke operator (-o)",
data: (target) => target.data("name"),
callback: deop,
});
}
function addVoiceItem() {
function voice(itemData) {
socket.emit("input", {
target: $("#chat").data("id"),
text: "/voice " + itemData,
});
}
addContextMenuItem({
check: (target) =>
utils.hasRoleInChannel(target.closest(".chan"), ["op"]) &&
!utils.hasRoleInChannel(target.closest(".chan"), ["voice"], target.data("name")),
className: "action-voice",
displayName: "Give voice (+v)",
data: (target) => target.data("name"),
callback: voice,
});
}
function addDevoiceItem() {
function devoice(itemData) {
socket.emit("input", {
target: $("#chat").data("id"),
text: "/devoice " + itemData,
});
}
addContextMenuItem({
check: (target) =>
utils.hasRoleInChannel(target.closest(".chan"), ["op"]) &&
utils.hasRoleInChannel(target.closest(".chan"), ["voice"], target.data("name")),
className: "action-voice",
displayName: "Revoke voice (-v)",
data: (target) => target.data("name"),
callback: devoice,
});
}
function addFocusItem() { function addFocusItem() {
function focusChan(itemData) { function focusChan(itemData) {
$(`.networks .chan[data-target="${itemData}"]`).click(); $(`.networks .chan[data-target="${itemData}"]`).click();
@ -206,6 +282,10 @@ function addDefaultItems() {
addWhoisItem(); addWhoisItem();
addQueryItem(); addQueryItem();
addKickItem(); addKickItem();
addOpItem();
addDeopItem();
addVoiceItem();
addDevoiceItem();
addFocusItem(); addFocusItem();
addChannelListItem(); addChannelListItem();
addBanListItem(); addBanListItem();

View file

@ -42,16 +42,16 @@ 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 one of the supplied roles. // Given a channel element will determine if the lounge user or a given nick is one of the supplied roles.
function hasRoleInChannel(channel, roles) { function hasRoleInChannel(channel, roles, nick) {
if (!channel || !roles) { if (!channel || !roles) {
return false; return false;
} }
const channelID = channel.data("id"); const channelID = channel.data("id");
const network = $("#sidebar .network").has(`.chan[data-id="${channelID}"]`); const network = $("#sidebar .network").has(`.chan[data-id="${channelID}"]`);
const ownNick = network.data("nick"); const target = nick || network.data("nick");
const user = channel.find(`.names-original .user[data-name="${escape(ownNick)}"]`).first(); const user = channel.find(`.names-original .user[data-name="${escape(target)}"]`).first();
return user.parent().is("." + roles.join(", .")); return user.parent().is("." + roles.join(", ."));
} }