diff --git a/notifyme/candy.css b/notifyme/candy.css index 913b926..a06bf91 100644 --- a/notifyme/candy.css +++ b/notifyme/candy.css @@ -1,3 +1,22 @@ .candy-notifyme-highlight { - background: #FFFF00; -} \ No newline at end of file + background: rgba(126, 245, 96, 0.1); + border: 1px solid rgba(86, 165, 66, 0.5); + border-radius: 3px; + padding: 2px 3px; +} + +#chat-tabs .mentions { + background-color: #149B1F; + border-radius: 50%; + color: white; + cursor: default; + font-size: 10px; + font-weight: bold; + height: 17px; + padding: 1px 4px; + position: absolute; + right: 41px; + top: 3px; + text-align: center; + width: 17px; +} diff --git a/notifyme/candy.js b/notifyme/candy.js index d37b38e..7de29db 100644 --- a/notifyme/candy.js +++ b/notifyme/candy.js @@ -3,8 +3,10 @@ * * Authors: * - Troy McCabe + * - Melissa Adamaitis * * Copyright: + * (c) 2014 Power Home Remodeling Group * (c) 2012 Geek Squad. All rights reserved. */ var CandyShop = (function(self) { return self; }(CandyShop || {})); @@ -13,71 +15,121 @@ var CandyShop = (function(self) { return self; }(CandyShop || {})); * Notifies with a sound and highlights the text in the chat when a nick is called out */ CandyShop.NotifyMe = (function(self, Candy, $) { - /** Object: _options - * Options for this plugin's operation - * - * Options: - * (String) nameIdentifier - Prefix to append to a name to look for. '@' now looks for '@NICK', '' looks for 'NICK', etc. Defaults to '@' - * (Boolean) playSound - Whether to play a sound when identified. Defaults to true - * (Boolean) highlightInRoom - Whether to highlight the name in the room. Defaults to true - */ - var _options = { - nameIdentifier: '@', - playSound: true, - highlightInRoom: true - }; + /** Object: _options + * Options for this plugin's operation + * + * Options: + * (String) nameIdentifier - Prefix to append to a name to look for. + * '@' now looks for '@NICK', '' looks for 'NICK', etc. Defaults to '@'. + * (Boolean) playSound - Whether to play a sound when identified. Defaults to true. + * (Boolean) highlightInRoom - Whether to highlight the name in the room. Defaults to true. + */ + var _options = { + nameIdentifier: '@', + playSound: true, + highlightInRoom: true + }; - /** Function: init - * Initialize the NotifyMe plugin - * Bind to beforeShow, play sound and higlight if specified - * - * Parameters: - * (Object) options - The options to apply to this plugin - */ - self.init = function(options) { - // apply the supplied options to the defaults specified - $.extend(true, _options, options); - - // get the nick from the current user - var nick = Candy.Core.getUser().getNick(); + /** Function: init + * Initialize the NotifyMe plugin + * Bind to beforeShow, play sound and higlight if specified + * + * Parameters: + * (Object) options - The options to apply to this plugin + */ + self.init = function(options) { + // Apply the supplied options to the defaults specified + $.extend(true, _options, options); - // make it what is searched - // search for name in the whole message - var searchTerm = _options.nameIdentifier + nick; + // Search for names and wrap them with a span element. + $(Candy).on('candy:view.message.before-render', function(e, args) { + // Ask for the nick each time because the nick can change. + var nickSearch = _options.nameIdentifier + Candy.Core.getUser().getNick(), + jidSearch = Candy.Core.getUser().getJid(), + cidSearch = _options.nameIdentifier + Strophe.getNodeFromJid(Candy.Core.getUser().getJid()), + nickRegExp = new RegExp(nickSearch, 'ig'), + jidRegExp = new RegExp(jidSearch, 'ig'), + cidRegExp = new RegExp(cidSearch, 'ig'); - // bind to the beforeShow event - $(Candy).on('candy:view.message.before-show', function(e, args) { - var searchRegExp = new RegExp('^(.*)(\s?' + searchTerm + ')', 'ig'); - - // if it's in the message and it's not from me, do stuff - // I wouldn't want to say 'just do @{MY_NICK} to get my attention' and have it knock... - if (searchRegExp.test(args.message) && args.name != nick) { - // play the sound if specified - if (_options.playSound) { - Candy.View.Pane.Chat.Toolbar.playSound(); - } - - // Save that I'm mentioned in args - args.forMe = true; - } - - return args.message; - }); - - // bind to the beforeShow event - $(Candy).on('candy:view.message.before-render', function(e, args) { - var searchRegExp = new RegExp('^(.*)(\s?' + searchTerm + ')', 'ig'); - - // if it's in the message and it's not from me, do stuff - // I wouldn't want to say 'just do @{MY_NICK} to get my attention' and have it knock... - if (searchRegExp.test(args.templateData.message) && args.templateData.name != nick) { - // highlight if specified - if (_options.highlightInRoom) { - args.templateData.message = args.templateData.message.replace(searchRegExp, '$1' + searchTerm + ''); - } - } - }); - }; + // If it's in the message and it's not from me, do stuff + if (args.templateData.name !== Candy.Core.getUser().getNick() && + self.containsMe(args.templateData.message)) { + // Highlight my name if configured to do so. + if (_options.highlightInRoom) { + args.templateData.message = args.templateData.message + .replace(nickRegExp, Mustache.to_html(self.Template.highlight, {message: nickSearch})) + .replace(jidRegExp, Mustache.to_html(self.Template.highlight, {message: jidSearch})) + .replace(cidRegExp, Mustache.to_html(self.Template.highlight, {message: cidSearch})); + } + // Play a notification sound if configured to do so. + if (_options.playSound) { + Candy.View.Pane.Chat.Toolbar.playSound(); + } + } + }); - return self; -}(CandyShop.NotifyMe || {}, Candy, jQuery)); \ No newline at end of file + // If I'm mentioned, display a special nofitication for the room. + $(Candy).on('candy:view.message.before-show', function(e, args) { + if ((!Candy.View.Pane.Window.hasFocus() || + !Candy.View.Pane.Room.getPane(args.roomJid).is(':visible')) && + self.containsMe(args.message)) { + var tab = Candy.View.Pane.Chat.getTab(args.roomJid); + + // Increase the mentions count. + Candy.View.Pane.Chat.rooms[args.roomJid].mentionsCount += 1; + + // Only insert one notification for mentions. + if ($(tab).find('.mentions').length <= 0) { + $(tab).find('.label').after(Mustache.to_html(self.Template.mentions, + {mentions: Candy.View.Pane.Chat.rooms[args.roomJid].mentionsCount})); + } else { + $(tab).find('.mentions').html(Candy.View.Pane.Chat.rooms[args.roomJid].mentionsCount); + } + } + }); + + // Clear mention notifications on window focus. + $(window).focus(function() { + var roomJid = Candy.View.getCurrent().roomJid; + if (roomJid) { + self.clearMentions(roomJid); + } + }); + + // Add a mention notification counter and set it at zero. + $(Candy).on('candy:view.room.after-add', function(e, args) { + Candy.View.Pane.Chat.rooms[args.roomJid].mentionsCount = 0; + }); + + // Clear mention notifications when moving to a window. + $(Candy).on('candy:view.room.after-show', function(e, args) { + self.clearMentions(args.roomJid); + }); + }; + + self.containsMe = function(message) { + var message = message.toLowerCase(), + nickSearch = _options.nameIdentifier + Candy.Core.getUser().getNick().toLowerCase(), + jidSearch = Candy.Core.getUser().getJid().toLowerCase(), + cidSearch = _options.nameIdentifier + Strophe.getNodeFromJid(Candy.Core.getUser().getJid()).toLowerCase(); + if (message.indexOf(nickSearch) !== -1 || + message.indexOf(jidSearch) !== -1 || + message.indexOf(cidSearch) !== -1) { + return true; + } + return false; + }; + + self.clearMentions = function(roomJid) { + var tab = Candy.View.Pane.Chat.getTab(roomJid); + Candy.View.Pane.Chat.rooms[roomJid].mentionsCount = 0; + $(tab).find('.mentions').remove(); + }; + + self.Template = { + highlight: '{{message}}', + mentions: '{{mentions}}' + }; + + return self; +}(CandyShop.NotifyMe || {}, Candy, jQuery));