diff --git a/client/css/style.css b/client/css/style.css index d74baf61..b483f0a1 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -1005,13 +1005,16 @@ kbd { padding-left: 20px; } -#chat table.channel-list { +#chat table.channel-list, +#chat table.ban-list { margin: 5px 10px; width: calc(100% - 30px); } #chat table.channel-list th, -#chat table.channel-list td { +#chat table.ban-list th, +#chat table.channel-list td, +#chat table.ban-list td { padding: 5px; vertical-align: top; border-bottom: #eee 1px solid; @@ -1022,7 +1025,10 @@ kbd { } #chat table.channel-list .channel, -#chat table.channel-list .topic { +#chat table.channel-list .topic, +#chat table.ban-list .hostmask, +#chat table.ban-list .banned_by, +#chat table.ban-list .banned_at { text-align: left; } diff --git a/client/index.html b/client/index.html index 7d751664..58884e6f 100644 --- a/client/index.html +++ b/client/index.html @@ -554,6 +554,15 @@ +
+
+ /banlist +
+
+

Load the banlist for the current channel.

+
+
+
/clear diff --git a/client/js/lounge.js b/client/js/lounge.js index 41505797..ab5713dc 100644 --- a/client/js/lounge.js +++ b/client/js/lounge.js @@ -20,6 +20,7 @@ $(function() { var commands = [ "/away", "/back", + "/banlist", "/close", "/connect", "/deop", @@ -247,6 +248,7 @@ $(function() { "whois", "ctcp", "channel_list", + "ban_list", ].indexOf(type) !== -1) { template = "msg_action"; } else if (type === "unhandled") { @@ -379,7 +381,7 @@ $(function() { var target = "#chan-" + data.chan; var container = chat.find(target + " .messages"); - if (data.msg.type === "channel_list") { + if (data.msg.type === "channel_list" || data.msg.type === "ban_list") { $(container).empty(); } diff --git a/client/views/actions/ban_list.tpl b/client/views/actions/ban_list.tpl new file mode 100644 index 00000000..c73ba7dc --- /dev/null +++ b/client/views/actions/ban_list.tpl @@ -0,0 +1,18 @@ + + + + + + + + + + {{#each bans}} + + + + + + {{/each}} + +
BannedBanned ByBanned At
{{hostmask}}{{{parse banned_by}}}{{{localetime banned_at}}}
diff --git a/client/views/index.js b/client/views/index.js index 0b92ab8e..fa1916ee 100644 --- a/client/views/index.js +++ b/client/views/index.js @@ -3,6 +3,7 @@ module.exports = { actions: { action: require("./actions/action.tpl"), + ban_list: require("./actions/ban_list.tpl"), channel_list: require("./actions/channel_list.tpl"), ctcp: require("./actions/ctcp.tpl"), invite: require("./actions/invite.tpl"), diff --git a/src/client.js b/src/client.js index 27387778..c7c57efb 100644 --- a/src/client.js +++ b/src/client.js @@ -17,6 +17,7 @@ var id = 0; var events = [ "connection", "unhandled", + "banlist", "ctcp", "error", "invite", diff --git a/src/models/msg.js b/src/models/msg.js index a3ce4bc8..3b36256e 100644 --- a/src/models/msg.js +++ b/src/models/msg.js @@ -20,7 +20,8 @@ Msg.Type = { CTCP: "ctcp", TOPIC: "topic", TOPIC_SET_BY: "topic_set_by", - WHOIS: "whois" + WHOIS: "whois", + BANLIST: "ban_list" }; module.exports = Msg; diff --git a/src/plugins/inputs/mode.js b/src/plugins/inputs/mode.js index b6ee5d80..8395da15 100644 --- a/src/plugins/inputs/mode.js +++ b/src/plugins/inputs/mode.js @@ -1,11 +1,10 @@ "use strict"; -exports.commands = ["mode", "op", "voice", "deop", "devoice"]; - var Chan = require("../../models/chan"); var Msg = require("../../models/msg"); exports.commands = [ + "banlist", "mode", "op", "deop", @@ -15,6 +14,10 @@ exports.commands = [ "devoice", ]; +const chanCommands = [ + "banlist" +]; + exports.input = function(network, chan, cmd, args) { if (cmd !== "mode") { if (chan.type !== Chan.Type.CHANNEL) { @@ -26,7 +29,7 @@ exports.input = function(network, chan, cmd, args) { return; } - if (args.length === 0) { + if (args.length === 0 && chanCommands.indexOf(cmd) === -1) { chan.pushMessage(this, new Msg({ type: Msg.Type.ERROR, text: `Usage: /${cmd} [...nick]` @@ -36,6 +39,7 @@ exports.input = function(network, chan, cmd, args) { } const mode = { + banlist: "+b", op: "+o", hop: "+h", voice: "+v", @@ -44,6 +48,9 @@ exports.input = function(network, chan, cmd, args) { devoice: "-v" }[cmd]; + if (chanCommands.indexOf(cmd) > -1 && args.length === 0) { + network.irc.raw("MODE", chan.name, mode); + } args.forEach(function(target) { network.irc.raw("MODE", chan.name, mode, target); }); diff --git a/src/plugins/irc-events/banlist.js b/src/plugins/irc-events/banlist.js new file mode 100644 index 00000000..d45d81cc --- /dev/null +++ b/src/plugins/irc-events/banlist.js @@ -0,0 +1,48 @@ +"use strict"; + +const Chan = require("../../models/chan"); +const Msg = require("../../models/msg"); + +module.exports = function(irc, network) { + const client = this; + + irc.on("banlist", function(banlist) { + const channel = banlist.channel; + const bans = banlist.bans; + if (!bans) { + const msg = new Msg({ + time: Date.now(), + type: Msg.Type.ERROR, + text: "Banlist empty" + }); + network.getChannel(channel).pushMessage(client, msg, true); + return; + } + + const chanName = `Banlist for ${channel}`; + let chan = network.getChannel(chanName); + if (typeof chan === "undefined") { + chan = new Chan({ + type: Chan.Type.SPECIAL, + name: chanName + }); + network.channels.push(chan); + client.emit("join", { + network: network.id, + chan: chan + }); + } + + chan.pushMessage(client, + new Msg({ + type: Msg.Type.BANLIST, + bans: bans.map((data) => ({ + hostmask: data.banned, + banned_by: data.banned_by, + banned_at: data.banned_at * 1000 + })) + }), + true + ); + }); +};