diff options
-rw-r--r-- | CHANGELOG.md (renamed from CHANGELOG) | 25 | ||||
-rw-r--r-- | commands.js | 89 | ||||
-rw-r--r-- | debugmiddleware.js | 11 | ||||
-rw-r--r-- | globals.js | 7 | ||||
-rw-r--r-- | handlers.js | 348 | ||||
-rw-r--r-- | index.html | 2 | ||||
-rw-r--r-- | index.js | 416 | ||||
-rw-r--r-- | main.js | 2 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | semantic.json | 56 | ||||
-rw-r--r-- | util.js | 31 |
11 files changed, 574 insertions, 417 deletions
@@ -1,4 +1,4 @@ -0.1.0 +0.0.1 ----- - Initial alpha release with basic IRC functionality and commands - Support /join and /part of channels @@ -7,13 +7,30 @@ - Can send /whois and channel /list commands - Interpret join, part, quit, kill, kick, and mode messages - Display topics and user lists in channels -0.1.1 + +0.0.2 ----- - Added ability to send PMs with /msg -0.2.0 + - In-line Image/Video/Audio/Youtube expansion + +0.1.0 ----- - Added basic connection UI at startup (automatically populated from config.json) -0.2.1 + +0.1.1 ----- - Create channel tab when names list is received, to support bouncers - Added SSL connection option + +0.1.2 +----- + - Add /topic command + - Fix /join command + - Windows electron fix + +0.2.0 +----- + - Migrate to irc-framework library + - Includes all functionality of 0.1.2 + - Show when and who set a topic + - Show more server and error messages diff --git a/commands.js b/commands.js new file mode 100644 index 0000000..1847b74 --- /dev/null +++ b/commands.js @@ -0,0 +1,89 @@ +var client +var globals = require('./globals.js') + +module.exports.init = function(myClient) { + client = myClient +} + +module.exports.sendMsg = function(message, channel) { + client.say(channel, message); + var chanTab = $("[data-tab='"+ channel +"'].chat"); + chanTab.append("<p class='chat-line'><" + globals.myNick + "> " + message +"</p>"); + chanTab.scrollTop(chanTab.prop("scrollHeight")); +} + +module.exports.sendPm = function(message, nick) { + + var chanTab = $("[data-tab="+nick+"].tab"); + $(".active").removeClass("active"); + numChans = globals.channels.length + if (chanTab.length == 0) { + $(".ui.menu").append("<a class='active item' data-id='"+numChans+"' data-tab='"+nick+"'>"+nick+"</a>"); + $("#chan-container").append("<div class='ui active tab' data-id='"+numChans+"' data-tab='"+nick+"'></div>"); + chanTab = $("[data-tab="+nick+"].tab"); + chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='"+nick+"'></div>"); + + $('.menu .item').tab({history:false}); + globals.channels.push(nick) + numChans++; + } + $("[data-tab="+nick+"]").addClass("active"); + var chatTab = $("[data-tab="+nick+"].chat"); + console.log(nick + ': ' + message); + client.say(nick, message); + chatTab.append("<p class='chat-line'><" + globals.myNick + "> " + message +"</p>"); + chatTab.scrollTop(chanTab.prop("scrollHeight")); +} + + +module.exports.setTopic = function(channel, topic) { + client.raw("TOPIC", channel, topic); +} + +module.exports.joinChannel = function (channel, sendJoin) { + + numChans = globals.channels.length + var channelObj = client.channel(channel); + if (sendJoin) { + channelObj.join(); + channelObj.say("beep"); + } + chanId = $(".active.chat").attr("data-id") + + $(".active").removeClass("active"); + + $(".ui.menu").append("<a class='active item' data-id='"+numChans+"' data-tab='"+channel+"'>"+channel+"</a>"); + $("#chan-container").append("<div class='ui active tab' data-id='"+numChans+"' data-tab='"+channel+"'></div>"); + + var chanTab = $("[data-tab='"+ channel +"'].tab"); + + chanTab.append("<div class='ui selection list users' data-id='"+numChans+"' data-tab='"+channel+"'></div>"); + chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='"+channel+"'></div>"); + chanTab.append("<div class='ui topic' data-id='"+numChans+"' data-tab='"+channel+"'></div>"); + + $('.menu .item').tab({history:false}); + globals.channels.push(channel) + numChans++; +} + +module.exports.removeChannel = function(channel, sendPart) { + + chanId = $("[data-tab='"+channel+"'].chat").attr("data-id"); + $("[data-tab='"+channel+"']").remove(); + if (sendPart) { + var channelObj = client.channel(channel) + channelObj.part(); + } + while ($("[data-id="+(chanId-1)+"]").length == 0 && chanId >=0) { + chanId--; + } + $("[data-id="+(chanId-1)+"]").addClass("active"); +} + +module.exports.whois = function(nick) { + client.whois(nick); +} + +module.exports.list = function() { + client.raw("LIST") +} diff --git a/debugmiddleware.js b/debugmiddleware.js new file mode 100644 index 0000000..9db3aeb --- /dev/null +++ b/debugmiddleware.js @@ -0,0 +1,11 @@ +module.exports.DebugMiddleware = function() { + return function(client, raw_events, parsed_events) { + parsed_events.use(theMiddleware); + } + + function theMiddleware(command, event, client, next) { + // console.log(command); + // console.log(event); + next(); + } +} diff --git a/globals.js b/globals.js new file mode 100644 index 0000000..d96f702 --- /dev/null +++ b/globals.js @@ -0,0 +1,7 @@ +module.exports.channels = ['status'] + +module.exports.pms = [] + +module.exports.networks = [] + +module.exports.myNick = "" diff --git a/handlers.js b/handlers.js new file mode 100644 index 0000000..9142f04 --- /dev/null +++ b/handlers.js @@ -0,0 +1,348 @@ +var linkify = require("linkifyjs"); +var linkifyHtml = require('linkifyjs/html'); +var util = require("./util.js") +var commands = require("./commands.js") +var globals = require("./globals.js") +var numChans = globals.channels.length + globals.pms.length; +var channels; +var client; +var myNick = "" +module.exports.setChannels = function(myChannels) { + channels = myChannels; +} +module.exports.handleCommands = function(myClient) { + client = myClient; + client.on('registered', function(event) { + channels.forEach(function(channelStr) { + commands.joinChannel(channelStr, true); + }); + }); + client.on('message', function(event) { + receiveMsg(event.target, event.nick, event.message, event.from_server) + }) + + client.on('userlist', function(event) { + channel = event.channel + if($(".ui.tab[data-tab='"+channel+"']").length == 0) { + commands.joinChannel(channel, false) + } + event.users.forEach(function (user) { + var nick = user.nick + var mode = "" + user.modes.forEach(function (modeChar) { + if (modeChar === "o") { + mode = "@" + } else if (modeChar === "h") { + mode = "%" + } else if (modeChar === "v") { + mode = "+" + } + }) + if($(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").length == 0) { + $(".ui.users[data-tab='"+channel+"']").append("<div class=item data-nick="+nick+">"+mode+nick+"</div>") + } + }) + }) + + client.on('topic', function(event) { + channel = event.channel + topic = event.topic + //TODO: Handle topicsetby to add the user and time for the topic + var chatTab = $("[data-tab='"+ channel +"'].chat"); + if($(".ui.tab[data-tab='"+channel+"']").length == 0) { + commands.joinChannel(channel, false) + } + chatTab.append("<p class='chat-line'>Topic for "+channel+" is "+topic+"</p>") + var topicTab = $("[data-tab='"+ channel +"'].topic"); + topicTab.html("<p class='topic-line'>"+topic+"</p>") + }) + + client.on('topicsetby', function(event) { + channel = event.channel + nick = event.nick + timestamp = event.when + + //TODO: Handle topicsetby to add the user and time for the topic + + var chatTab = $("[data-tab='"+ channel +"'].chat"); + if($(".ui.tab[data-tab='"+channel+"']").length == 0) { + commands.joinChannel(channel, false) + } + chatTab.append("<p class='chat-line'>Set by "+nick+" at "+timestamp+"</p>") + var topicLine = $("[data-tab='"+ channel +"'].topic .topic-line"); + topicLine.append(" by " + nick + " at " + timestamp) + }) + + client.on('whois', function(event) { + var nick = event.nick + var chatTab = $(".active .chat"); + chatTab.append("<p class='chat-line'>"+event.nick+": "+event.user+"@"+event.host+"</p>"); + chatTab.append("<p class='chat-line'> Real Name: "+event.real_name+"</p>"); + chatTab.append("<p class='chat-line'> Channels: " + event.channels+"</p>"); + chatTab.append("<p class='chat-line'> Server: "+event.server+" "+event.server_info+"</p>"); + if (event.operator.length > 0) { + chatTab.append("<p class='chat-line'>"+event.operator+"</p>"); + } + if (event.registered_nick.length > 0) { + chatTab.append("<p class='chat-line'>"+event.registered_nick+"</p>"); + } + if (event.away.length > 0) { + chatTab.append("<p class='chat-line'>"+event.away+"</p>"); + } + if (event.secure) { + chatTab.append("<p class='chat-line'>is using a secure connection</p>"); + } + chatTab.scrollTop(chatTab.prop("scrollHeight")); + + }) + + client.on('channel list', function(event) { + var statusTab = $("[data-tab='status'].chat"); + statusTab.append("<p class='chat-line'>Channel List:</p>") + event.forEach( function(channel) { + if (channel.topic.length == 0) { + statusTab.append("<p class='chat-line'>"+channel.channel+" ("+channel.num_users+")</p>"); + } else { + statusTab.append("<p class='chat-line'>"+channel.channel+" ("+channel.num_users+") : "+channel.topic+"</p>"); + } + statusTab.scrollTop(statusTab.prop("scrollHeight")); + }) + }) + + + client.on('join', function(event) { + var channel = event.channel + var nick = event.nick + if($(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").length == 0) { + $(".ui.users[data-tab='"+channel+"']").append("<div class=item data-nick="+nick+">"+nick+"</div>") + } + var chatTab = $("[data-tab='"+ channel +"'].chat"); + chatTab.append("<p class='chat-line'>"+nick+" joined "+channel+"</p>") + }); + + client.on('part', function(event) { + var channel = event.channel + var nick = event.nick + var message = event.message + + if($(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").length > 0) { + $(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").remove(); + } + var chatTab = $("[data-tab='"+ channel +"'].chat"); + + chatTab.append("<p class='chat-line'>"+nick+" left "+channel+" ("+message+")</p>") + chatTab.scrollTop(chatTab.prop("scrollHeight")); + }); + + client.on('quit', function(event) { + var nick = event.nick + var message = event.message + + + globals.channels.forEach(function(channel) { + if($(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").length > 0) { + $(".ui.users[data-tab='"+channel+"'] [data-nick="+nick+"]").remove(); + var chatTab = $("[data-tab='"+ channel +"'].chat"); + chatTab.append("<p class='chat-line'>"+nick+" quit ("+message+")</p>") + chatTab.scrollTop(chatTab.prop("scrollHeight")); + } + + }); + }) + + client.on('mode', function(event) { + var chatTab = $("[data-tab='"+ channel +"'].chat"); + var by = event.nick + var channel = event.target + event.modes.forEach(function (modeObj) { + + var mode = modeObj.mode + var argument = modeObj.param + if (mode == "+o") { + modeLine = " gives channel operator status to " + argument; + } else if (mode == "+v") { + modeLine = " gives voice to " + argument; + } else if (mode == "+h") { + modeLine = " gives channel half-operator status to " + argument; + } else if (mode == "+q") { + modeLine = " gives channel owner status to " + argument; + } else if (mode == "-o") { + modeLine = " removes channel operator status from " + argument; + } else if (mode == "-v") { + modeLine = " removes voice from "; + } else if (mode == "-h") { + modeLine = " removes channel half-operator status from " + argument; + } else if (mode == "-q") { + modeLine = " removes channel owner status from " + argument; + } else if (argument == globals.myNick) { + modeLine = " sets mode " + mode + " on " + argument; + } else if (argument != null) { + modeLine = " sets mode " + mode + " " + argument + " on " +channel; + } else { + modeLine = " sets mode "+mode+" on " +channel + } + var chatTab = $("[data-tab='"+ channel +"'].chat"); + chatTab.append("<p class='chat-line'>"+by+modeLine+"</p>"); + }) + chatTab.scrollTop(chatTab.prop("scrollHeight")); + }) + + client.on('kick', function(event) { + var kicked = event.kicked + var by = event.nick + var channel = event.channel + var reason = event.message + if (globals.myNick == kicked) { + commands.removeChannel(channel, false); + } else { + if($(".ui.users[data-tab='"+channel+"'] [data-nick="+kicked+"]").length > 0) { + $(".ui.users[data-tab='"+channel+"'] [data-nick="+kicked+"]").remove(); + } + var chatTab = $("[data-tab='"+ channel +"'].chat"); + chatTab.append("<p class='chat-line'>"+kicked+" was kicked from "+channel+" by "+by+" ("+reason+")</p>") + chatTab.scrollTop(chatTab.prop("scrollHeight")); + } + }) + + client.on('motd', function(event) { + serverMsg(event.motd) + }) + + //Server Info + //eg: Your host is irc.lc8n.com, running version Unreal3.2.10.4" + //param 0 is your nick + client.on('002', function(event) { + serverMsg(event.params[1]) + }) + + //Server created + //eg Your host is irc.lc8n.com, running version Unreal3.2.10.4" + //param 0 is your nick + client.on('003', function(event) { + serverMsg(event.params[1]) + }) + + //004: Some unknown server strings + client.on('004', function(event) { + serverMsg(event.params[1] + " " + event.params[2] + " " + event.params[3] + " " + event.params[4]) + }) + //Users online + //eg: There are 7 users and 47 invisible on 4 servers + client.on('251', function(event) { + serverMsg(event.params[1]) + }) + + //Operators online + //eg: "10" "operator(s) online" + client.on('252', function(event) { + serverMsg(event.params[1] + " " +event.params[2]) + }) + + //Channels formed + //eg "49" "channels formed" + client.on('254', function(event) { + serverMsg(event.params[1] + " " +event.params[2]) + }) + + //'Clients' and 'Servers'? + //eg "I have 8 clients and 1 servers" + client.on('255', function(event) { + serverMsg(event.params[1]) + }) + + //User stats + //eg ""Current global users 54, max 63" + //param 0 is your nick, 1 is current users, 2 is max users + client.on('266', function(event) { + serverMsg(event.params[3]) + }) + + client.on('irc error', function(event) { + errorMsg(event.error, event.reason, event.channel) + }); + + //No such channel error + client.on('403', function(event) { + errorMsg("403", event.params[2], event.params[1]) + }); +} + + +function errorMsg(error, message, param) { + var chatTab = $(".active .chat"); + + chatTab.append("<p class='chat-line'>Error: "+error+"!</p>"); + if (param.length > 0) { + chatTab.append("<p class='chat-line'>Param: "+param+"</p>"); + } + if (message.length > 0) { + chatTab.append("<p class='chat-line'>Message: "+message+"</p>"); + } + chatTab.scrollTop(chatTab.prop("scrollHeight")); + console.log('error: ', error); +} +function serverMsg(message) { + var statusTab = $("[data-tab=status].chat"); + statusTab.append("<p class='chat-line'>"+message+"</p>") + statusTab.scrollTop(statusTab.prop("scrollHeight")); +} + +function receiveMsg(target, from, message, from_server) { + // message = message.autoLink( { + // callback: function(url) { + // return /\.(gif|png|jpe?g)$/i.test(url) ? '<img src="' + url + '">' : null; + // }, + // target: "_blank" + // }); + // console.log(message.autoLink()); + + if (from_server) { + serverMsg(message) + return false + } + numChans = globals.channels.length + console.log(from + ' => '+ target +': ' + message); + + if (target === client.user.nick) { + target = from + } + var chatTab = $("[data-tab='"+ target +"'].chat"); + + if (chatTab.length == 0) { + $(".ui.menu").append("<a class='item' data-id='"+numChans+"' data-tab='"+target+"'>"+target+"</a>"); + $("#chan-container").append("<div class='ui tab' data-id='"+numChans+"' data-tab='"+target+"'></div>"); + chanTab = $("[data-tab="+target+"].tab"); + chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='"+target+"'></div>"); + + $('.menu .item').tab({history:false}); + global.channels.push(target) + numChans++; + chatTab = $("[data-tab="+ target +"].chat"); + } + + message = linkifyHtml(message); + + chatTab.append("<p class='chat-line'><" + from + "> " + message +"</p>"); + var imgMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(gif|png|jpe?g|bmp)/); + var vidMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(webm|mp4)/); + var audioMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(mp3|wav|ogg)/); + var youtubeMatch = message.match(/(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/(watch\?v=)?[a-z0-9A-Z_\-]+/); + if (imgMatch != null && imgMatch.length > 0) { + var image = util.imagify(imgMatch[0],target); + chatTab.append("<p class=chat-line>"+image+"</p>"); + } + if (vidMatch != null && vidMatch.length > 0) { + chatTab.append("<p class=chat-line><video controls><source src="+vidMatch[0]+"></video></p>"); + } + if (audioMatch != null && audioMatch.length > 0) { + chatTab.append("<p class=chat-line><audio controls><source src="+audioMatch[0]+"></audio></p>"); + } + if (youtubeMatch != null && youtubeMatch.length > 0) { + youtubeParts = youtubeMatch[0].split("/"); + youtubeId = youtubeParts[youtubeParts.length-1]; + youtubeId = youtubeId.replace("watch?v=",""); + chatTab.append("<p class=chat-line><iframe width='480' height='270' src='https://www.youtube.com/embed/"+youtubeId+"' frameborder='0' allowfullscreen></iframe></p>"); + } + + chatTab.scrollTop(chatTab.prop("scrollHeight")); +} @@ -53,7 +53,7 @@ window.$ = window.jQuery = require('./lib/jquery-2.2.2.js'); blachat = require("./index.js"); function scrollToTop(channel) { - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); + var chatTab = $("[data-tab="+ channel +"].chat"); chatTab.scrollTop(chatTab.prop('scrollHeight')); } </script> @@ -1,12 +1,17 @@ -var linkify = require("linkifyjs"); -var linkifyHtml = require('linkifyjs/html'); + var shell = require('electron').shell; var config = require('./config.json') var pjson = require('./package.json'); +var handlers = require('./handlers.js'); +var commands = require('./commands.js'); +var globals = require('./globals.js') +var debugmiddleware = require('./debugmiddleware.js'); const progName = pjson.name; const version = pjson.version; var myNick = config.nick; - +var server = config.server; +var port = config.port; +var password = config.password; $(document).ready(function() { $("#send-message").focus(); }); @@ -16,7 +21,8 @@ $(document).on('click', 'a[href^="http"]', function(event) { shell.openExternal(this.href); }); -const irc = require('irc'); +const IRC = require('irc-framework'); +const client = new IRC.Client() $("#server-input").val(config.server); $("#port-input").val(config.port); @@ -31,24 +37,32 @@ config.channels.forEach(function(channel) { txtChannels = txtChannels.substring(0, txtChannels.length-1) $("#channel-input").val(txtChannels); -var client; $('#connect').on('click', function() { -console.log($("#channel-input").val()); + server = $("#server-input").val(); + port = $("#port-input").val(); channels = $("#channel-input").val().split(" "); - myNick = $("#nick-input").val() + myNick = $("#nick-input").val(); + password = $("#password-input").val(); ssl = ($("#ssl-input:checked").val() == "on"); - console.log(ssl); - client = new irc.Client($("#server-input").val(), myNick, { - channels: channels, - userName: myNick, - password: $("#password-input").val(), - port: $("#port-input").val(), - secure: ssl, - selfSigned: true, - certExpired: true -}); - createListeners(client); + client.use(debugmiddleware.DebugMiddleware()); + client.connect({ + host: server, + port: port, + nick: myNick, + username: myNick, + gecos: myNick, + password: password, + tls: ssl, + rejectUnauthorized: false, + version: pjson.name + " " + pjson.version + }); + + globals.myNick = myNick + commands.init(client) + handlers.setChannels(channels) + handlers.handleCommands(client) + $("#chan-container").show(); @@ -57,10 +71,6 @@ console.log($("#channel-input").val()); }); - - - - function imagify(url, channel) { console.log(url); $.ajax({ @@ -92,363 +102,57 @@ function humanize(size) { return s + ' ' + units[ord]; } -var numChans = 1; +var numChans = globals.channels.length $("#send-message").keypress(function(e) { if(e.which == 13) { var message = $("#send-message").val(); - var channel = $(".tab.active").attr("data-tab").replace("chan-", "#") + var channel = $(".tab.active").attr("data-tab") if (message.indexOf("/join") == 0) { - joinChannel(message.substring(6, message.length), true); + commands.joinChannel(message.substring(6, message.length), true); } else if (message.indexOf("/part") == 0) { if (message.length > 6) { channel = message.substring(6, message.length); } - console.log() - removeChannel(channel, true); + commands.removeChannel(channel, true); } else if (message.indexOf("/whois") == 0) { - console.log("whois "+message.substring(7, message.length)); - client.whois(message.substring(7, message.length)); + commands.whois(message.substring(7, message.length)) + } else if (message.indexOf("/list") == 0) { - client.list(); + commands.list(); } else if (message.indexOf("/msg") == 0) { nick = message.split(" ")[1]; message = message.substring(6+nick.length, message.length); - sendPm(message, nick); + commands.sendPm(message, nick); } else if (message.indexOf("/topic") == 0) { - var channel = $(".tab.active").attr("data-tab").replace("chan-", "#") + var channel = $(".tab.active").attr("data-tab") topic = message.substring(7, message.length); - setTopic(channel, topic); + commands.setTopic(channel, topic); } else if (message.indexOf("/") == 0) { - command = message.split(" ")[0].replace("/",""); - commandArgs = message.replace(command + " ", ""); - client.send("kick", ["#wtest", "wjoe__", "test"]); + // command = message.split(" ")[0].replace("/",""); + // commandArgs = message.replace(command + " ", ""); + // client.send("kick", ["#wtest", "wjoe__", "test"]); } else { var tab = $(".tab.active").attr("data-tab"); - if (tab.startsWith("chan-")) { - sendMsg(message, channel); + if (tab.startsWith("#")) { + commands.sendMsg(message, channel); - } else if(tab.startsWith("pm-")){ - sendPm(message, tab.substring(3, tab.length)); + } else { + commands.sendPm(message, tab); } } $("#send-message").val(''); } }); -function sendMsg(message, channel) { - client.say(channel, message); - var chanTab = $("[data-tab=chan-"+ channel.replace("#","") +"].chat"); - chanTab.append("<p class='chat-line'><" + myNick + "> " + message +"</p>"); - chanTab.scrollTop(chanTab.prop("scrollHeight")); -} - -function sendPm(message, nick) { - - var chanTab = $("[data-tab=pm-"+nick+"].tab"); - $(".active").removeClass("active"); - if (chanTab.length == 0) { - $(".ui.menu").append("<a class='active item' data-id='"+numChans+"' data-tab='pm-"+nick+"'>"+nick+"</a>"); - $("#chan-container").append("<div class='ui active tab' data-id='"+numChans+"' data-tab='pm-"+nick+"'></div>"); - chanTab = $("[data-tab=pm-"+nick+"].tab"); - chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='pm-"+nick+"'></div>"); - - $('.menu .item').tab({history:false}); - numChans++; - } - $("[data-tab=pm-"+nick+"]").addClass("active"); - var chatTab = $("[data-tab=pm-"+nick+"].chat"); - console.log(nick + ': ' + message); - client.say(nick, message); - chatTab.append("<p class='chat-line'><" + myNick + "> " + message +"</p>"); - chatTab.scrollTop(chanTab.prop("scrollHeight")); -} - -function setTopic(channel, topic) { - client.send("TOPIC", channel, topic); -} - -function joinChannel(channel, sendJoin) { - if (sendJoin) { - client.join(channel); - } - channel = channel.replace("#",""); - chanId = $(".active.chat").attr("data-id") - - $(".active").removeClass("active"); - - $(".ui.menu").append("<a class='active item' data-id='"+numChans+"' data-tab='chan-"+channel+"'>#"+channel+"</a>"); - $("#chan-container").append("<div class='ui active tab' data-id='"+numChans+"' data-tab='chan-"+channel+"'></div>"); - - var chanTab = $("[data-tab=chan-"+ channel +"].tab"); - - chanTab.append("<div class='ui selection list users' data-id='"+numChans+"' data-tab='chan-"+channel+"'></div>"); - chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='chan-"+channel+"'></div>"); - chanTab.append("<div class='ui topic' data-id='"+numChans+"' data-tab='chan-"+channel+"'></div>"); - - $('.menu .item').tab({history:false}); - - - client.addListener('message#'+channel, function (from, message) { - // message = message.autoLink( { - // callback: function(url) { - // return /\.(gif|png|jpe?g)$/i.test(url) ? '<img src="' + url + '">' : null; - // }, - // target: "_blank" - // }); - // console.log(message.autoLink()); - console.log(from + ' => #'+ channel +': ' + message); - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - message = linkifyHtml(message); - - chatTab.append("<p class='chat-line'><" + from + "> " + message +"</p>"); - var imgMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(gif|png|jpe?g|bmp)/); - var vidMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(webm|mp4)/); - var audioMatch = message.match(/[a-z0-9\-]+[\.:]\S+\.(mp3|wav|ogg)/); - var youtubeMatch = message.match(/(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/(watch\?v=)?[a-z0-9A-Z_\-]+/); - if (imgMatch != null && imgMatch.length > 0) { - var image = imagify(imgMatch[0],channel); - chatTab.append("<p class=chat-line>"+image+"</p>"); - } - if (vidMatch != null && vidMatch.length > 0) { - chatTab.append("<p class=chat-line><video controls><source src="+vidMatch[0]+"></video></p>"); - } - if (audioMatch != null && audioMatch.length > 0) { - chatTab.append("<p class=chat-line><audio controls><source src="+audioMatch[0]+"></audio></p>"); - } - if (youtubeMatch != null && youtubeMatch.length > 0) { - console.log(youtubeMatch) - youtubeParts = youtubeMatch[0].split("/"); - youtubeId = youtubeParts[youtubeParts.length-1]; - youtubeId = youtubeId.replace("watch?v=",""); - chatTab.append("<p class=chat-line><iframe width='480' height='270' src='https://www.youtube.com/embed/"+youtubeId+"' frameborder='0' allowfullscreen></iframe></p>"); - } - - chatTab.scrollTop(chatTab.prop("scrollHeight")); - }); - numChans++; -} - -function removeChannel(channel, sendPart) { - channel = channel.replace("#",""); - chanId = $("[data-tab=chan-"+channel+"].chat").attr("data-id"); - $("[data-tab=chan-"+channel+"]").remove(); - if (sendPart) { - client.part("#"+channel); - } - while ($("[data-id="+(chanId-1)+"]").length == 0 && chanId >=0) { - chanId--; - } - $("[data-id="+(chanId-1)+"]").addClass("active"); -} - -function createListeners(client) { - - -client.addListener('error', function(message) { - console.log('error: ', message); -}); - -client.addListener('registered', function() { - channels.forEach(function(channel) { - joinChannel(channel, false); - }); -}); - -client.addListener('motd', function(motd) { - var statusTab = $("[data-tab=status].chat"); - statusTab.append("<p class='chat-line'>"+motd+"</p>") - statusTab.scrollTop(statusTab.prop("scrollHeight")); -}); -client.addListener('raw', function(message) { - var statusTab = $("[data-tab=status].chat"); - statusCmds = ["NOTICEAUTH", "rpl_welcome, rpl_yourhoust", "rpl_created", "rpl_myinfo", "rpl_isupport", "rpl_luserclient", "rpl_luserop", "rpl_luserme", "rpl_luserchannels", "rpl_localusers", "rpl_globalusers"]; - if (statusCmds.indexOf(message.command) > -1 || message.command.startsWith("rpl_")) { - statusTab.append("<p class='chat-line'>"+message.command + ": " +message.args+"</p>") - statusTab.scrollTop(statusTab.prop("scrollHeight")); - } -}); - -client.addListener('ctcp-version', function(from, to, text, message) { - client.ctcp(from, "VERSION", "VERSION "+progName + " v"+ version) -}); - - -client.addListener('names', function(channel, nicks) { - channel = channel.replace("#","") - if($(".ui.tab[data-tab=chan-"+channel+"]").length == 0) { - joinChannel(channel, false) - } - for(nick in nicks) { - var mode = nicks[nick]; - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length == 0) { - $(".ui.users[data-tab=chan-"+channel+"]").append("<div class=item data-nick="+nick+">"+mode+nick+"</div>") - } - } -}); -- -client.addListener('join', function(channel, nick) { - channel = channel.replace("#","") - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length == 0) { - $(".ui.users[data-tab=chan-"+channel+"]").append("<div class=item data-nick="+nick+">"+nick+"</div>") - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+nick+" joined #"+channel+"</p>") -}); - -client.addListener('part', function(channel, nick) { - channel = channel.replace("#","") - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length > 0) { - $(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").remove(); - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+nick+" left #"+channel+"</p>") - chatTab.scrollTop(chatTab.prop("scrollHeight")); -}); - -client.addListener('quit', function(nick, reason, channels, message) { - channels.forEach(function(channel) { - channel = channel.replace("#","") - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length > 0) { - $(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").remove(); - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+nick+" quit ("+reason+")</p>") - chatTab.scrollTop(chatTab.prop("scrollHeight")); - }); - -}); - -client.addListener('pm', function(nick, text, message) { - - if($(".ui.tab[data-tab=pm-"+nick+"]").length == 0) { - $(".ui.menu").append("<a class='item' data-id='"+numChans+"' data-tab='pm-"+nick+"'>"+nick+"</a>"); - $("#chan-container").append("<div class='ui tab' data-id='"+numChans+"' data-tab='pm-"+nick+"'></div>"); - var chanTab = $("[data-tab=pm-"+ nick +"].tab"); - chanTab.append("<div class='ui segment chat' data-id='"+numChans+"' data-tab='pm-"+nick+"'></div>"); - numChans++; - $('.menu .item').tab({history:false}); - } - var chatTab = $("[data-tab=pm-"+ nick +"].chat"); - chatTab.append("<p class='chat-line'><"+nick+"> "+text+"</p>") - chatTab.scrollTop(chatTab.prop("scrollHeight")); -}); - -client.addListener('kick', function(channel, nick, by, reason, message) { - if (myNick == nick) { - removeChannel(channel, false); - } else { - channel = channel.replace("#",""); - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length > 0) { - $(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").remove(); - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+nick+"was kicked from #"+channel+" by "+by+" ("+reason+")</p>") - chatTab.scrollTop(chatTab.prop("scrollHeight")); - } -}); - -client.addListener('kill', function(nick, reason, channels, message) { - channels.forEach(function(channel) { - channel = channel.replace("#","") - if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length > 0) { - $(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").remove(); - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+nick+" was killed by the server ("+reason+")</p>") - chatTab.scrollTop(chatTab.prop("scrollHeight")); - }); -}); - -client.addListener('topic', function(channel, topic, nick, message) { - channel = channel.replace("#",""); - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - if($(".ui.tab[data-tab=chan-"+channel+"]").length == 0) { - joinChannel(channel, false) - } - chatTab.append("<p class='chat-line'>Topic for #"+channel+" is "+topic+" - set by "+nick+" at "+message.args[3]+"</p>") - var topicTab = $("[data-tab=chan-"+ channel +"].topic"); - topicTab.html("<p class='topic-line'>"+topic+"</p>") -}); - -client.addListener('whois', function(info) { - console.log(info) - var chatTab = $(".active .chat"); - chatTab.append("<p class='chat-line'> Nick:"+info.nick+"</p>"); - chatTab.append("<p class='chat-line'> User:"+info.user+"</p>"); - chatTab.append("<p class='chat-line'> Host:"+info.host+"</p>"); - chatTab.append("<p class='chat-line'> Real Name:"+info.realname+"</p>"); - chatTab.append("<p class='chat-line'> Channels:"); - for (channel in info.channels) { - chatTab.append(" "+info.channels[channel]) - } - chatTab.append("</p>") - chatTab.append("<p class='chat-line'> Server:"+info.server+"</p>"); - chatTab.append("<p class='chat-line'> Server Info:"+info.serverinfo+"</p>"); - chatTab.append("<p class='chat-line'>"+info.operator+"</p>"); - chatTab.scrollTop(chatTab.prop("scrollHeight")); -}); - -client.addListener('+mode', function(channel, by, mode, argument, message) { - console.log(message) - channel = channel.replace("#","") - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - var modeLine = mode; - if (mode == "o") { - modeLine = " gives channel operator status to " + argument; - } else if (mode == "v") { - modeLine = " gives voice to " + argument; - } else if (mode == "h") { - modeLine = " gives channel half-operator status to " + argument; - } else if (mode == "q") { - modeLine = " gives channel owner status to " + argument; - } else if (argument == myNick) { - modeLine = " sets mode +" + mode + " on " + argument; - } else if (argument != null) { - modeLine = " sets mode " + mode + " " + argument + " on #" +channel; - } else { - modeLine = " sets mode +"+mode+" on #" +channel - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+by+modeLine+"</p>"); - chatTab.scrollTop(chatTab.prop("scrollHeight")); -}); - -client.addListener('-mode', function(channel, by, mode, argument, message) { - channel = channel.replace("#","") - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - var modeLine = mode; - if (mode == "o") { - modeLine = " removes channel operator status from "; - } else if (mode == "v") { - modeLine = " removes voice from "; - } else if (mode == "h") { - modeLine = " removes channel half-operator status from "; - } else if (mode == "q") { - modeLine = " removes channel owner status from "; - } else if (argument == myNick) { - modeLine = " sets mode -"+mode+" on " + argument; - } else if (argument != null) { - modeLine = " sets mode -" + mode + " " + argument + " on #" +channel; - } else { - modeLine = " sets mode -"+mode+" on #" +channel - } - var chatTab = $("[data-tab=chan-"+ channel +"].chat"); - chatTab.append("<p class='chat-line'>"+by+modeLine+"</p>"); - chatTab.scrollTop(chatTab.prop("scrollHeight")); -}); - -client.addListener('channellist', function(channelList) { - var statusTab = $("[data-tab=status].chat"); - statusTab.append("<p class='chat-line'>Channel List:</p>") - for (i in channelList) { - if (channelList[i].topic == null) { - statusTab.append("<p class='chat-line'>"+channelList[i].name+" ("+channelList[i].users+")</p>"); - } else { - statusTab.append("<p class='chat-line'>"+channelList[i].name+" ("+channelList[i].users+") : "+channelList[i].topic+"</p>"); - } - statusTab.scrollTop(statusTab.prop("scrollHeight")); - } -}); - -} +// client.addListener('kill', function(nick, reason, channels, message) { +// channels.forEach(function(channel) { +// channel = channel.replace("#","") +// if($(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").length > 0) { +// $(".ui.users[data-tab=chan-"+channel+"] [data-nick="+nick+"]").remove(); +// } +// var chatTab = $("[data-tab=chan-"+ channel +"].chat"); +// chatTab.append("<p class='chat-line'>"+nick+" was killed by the server ("+reason+")</p>") +// chatTab.scrollTop(chatTab.prop("scrollHeight")); +// }); +// }); @@ -24,7 +24,7 @@ app.on('window-all-closed', function() { // initialization and is ready to create browser windows. app.on('ready', function() { // Create the browser window. - mainWindow = new BrowserWindow({width: 800, height: 600, title: "blachat"}); + mainWindow = new BrowserWindow({width: 1000, height: 800, title: "blachat"}); // and load the index.html of the app. mainWindow.loadURL('file://' + __dirname + '/index.html'); diff --git a/package.json b/package.json index d635fce..3425300 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blachat", - "version": "0.2.1", + "version": "0.2.0", "description": "A modern IRC client", "license": "GPL-3.0", "repository": "http://www.blatech.co.uk/wjoe/blachat", @@ -8,6 +8,6 @@ "dependencies": { "semantic-ui": "^2.1.8", "linkifyjs": "2.0.0-beta.9", - "irc": "0.5.0", + "irc-framework": "2.0.0", "electron-prebuilt": "0.37.3" } } diff --git a/semantic.json b/semantic.json index 41c6498..8f70635 100755..100644 --- a/semantic.json +++ b/semantic.json @@ -16,57 +16,7 @@ "clean": "dist/" }, "permission": false, - "rtl": "No", - "components": [ - "reset", - "site", - "button", - "container", - "divider", - "flag", - "header", - "icon", - "image", - "input", - "label", - "list", - "loader", - "rail", - "reveal", - "segment", - "step", - "breadcrumb", - "form", - "grid", - "menu", - "message", - "table", - "ad", - "card", - "comment", - "feed", - "item", - "statistic", - "accordion", - "checkbox", - "dimmer", - "dropdown", - "embed", - "modal", - "nag", - "popup", - "progress", - "rating", - "search", - "shape", - "sidebar", - "sticky", - "tab", - "transition", - "api", - "form", - "state", - "visibility" - ], - "version": "2.1.8" + "autoInstall": false, + "rtl": false, + "version": "2.2.4" }
\ No newline at end of file @@ -0,0 +1,31 @@ + +module.exports.imagify = function(url, channel) { + console.log(url); + $.ajax({ + type: 'HEAD', + url: url, + complete: function(xhr) { + var type = xhr.getResponseHeader('Content-Type') + var size = xhr.getResponseHeader('Content-Length'); + console.log(type); + console.log(size); + if (size < 10000000) { + $("[data-img='"+url+"']").append("("+humanize(size)+")"); + $("[data-img='"+url+"']").append("<p class='chat-line'><img src="+url+" onload=scrollToTop('"+channel+"')></p>"); + $("[data-img='"+url+"']").removeClass("loading"); + + } + + } + }); + + return "<div data-img='"+url+"' class='ui image loading'></div>"; + +} + +humanize = function(size) { + var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB']; + var ord = Math.floor(Math.log(size) / Math.log(1000)); + var s = Math.round((size / Math.pow(1000, ord)) * 100) / 100; + return s + ' ' + units[ord]; +} |