-
-
Save garyharan/257574 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://cheeaun.talkerapp.com/plugins/82 | |
// jQuery.nano template engine | |
// http://github.com/trix/nano | |
(function(c){c.nano=function(d,e){return d.replace(/\{([\w\.]*)}/g,function(a,f){a=f.split(".");var b=e[a.shift()];c.each(a,function(){b=b[this]});return b})}})(jQuery); | |
var vendorStyles = function(str){ | |
var s = str.split('-'); | |
if (s.length == 4 && s[0] == 'border'){ | |
var value = s[3].split(':')[1]; | |
return str + '-webkit-' + str + '-moz-border-radius-' + s[1] + s[2] + ':' + value + ';'; | |
} | |
return str + '-moz-' + str + '-webkit-' + str; | |
}; | |
var $style = $('<style>' | |
+ '.talkerapp-private-chat-pane{' | |
+ 'position: fixed; bottom: 0; right: 10px; width: 240px; height: 20em; background-color: #fff; z-index: 100;' | |
+ vendorStyles('box-shadow: 0 0 10px #666;') | |
+ vendorStyles('border-top-left-radius: 3px;') | |
+ vendorStyles('border-top-right-radius: 3px;') | |
+ '}' | |
+ '.talkerapp-private-chat-pane.collapsed{' | |
+ 'height: 24px;' | |
+ '}' | |
+ '.talkerapp-private-chat-head{' | |
+ 'height: 24px; line-height: 24px; font-weight: bold; padding: 0 .5em; color: #fff; background-color: #4091BF; cursor: pointer;' | |
+ vendorStyles('border-top-left-radius: 3px;') | |
+ vendorStyles('border-top-right-radius: 3px;') | |
+ '}' | |
+ '.talkerapp-private-chat-pane.new-msg .talkerapp-private-chat-head{' | |
+ 'background-color: #EF9E2D;' | |
+ '}' | |
+ '.talkerapp-private-chat-pane .talkerapp-private-chat-head .close{' | |
+ 'width: 16px; height: 16px; text-align: center; line-height: 16px; position: absolute; top: 4px; right: 4px;' | |
+ 'color: #fff; text-decoration: none;' | |
+ vendorStyles('border-radius: 3px;') | |
+ '}' | |
+ '.talkerapp-private-chat-pane .talkerapp-private-chat-head .close:hover{' | |
+ 'background-color: rgba(0,0,0,.2)' | |
+ '}' | |
+ '.talkerapp-private-chat-body{' | |
+ 'position: absolute; top: 24px; left: 0; bottom: 0; right: 0; overflow: hidden;' | |
+ '}' | |
+ '.talkerapp-private-chat-body ol{' | |
+ 'margin: 0; padding: 0; list-style: none; position: absolute; top: 0; left: 0; bottom: 48px; width: 100%; overflow: auto;' | |
+ '}' | |
+ '.talkerapp-private-chat-body ol li{' | |
+ 'margin: 0; padding: 0 .5em; list-style: none; display: block; font-size: .9em; line-height: 1.5em;' | |
+ '}' | |
+ '.talkerapp-private-chat-body ol li .talker{' | |
+ 'font-weight: bold; float: left; margin-right: .5em;' | |
+ '}' | |
+ '.talkerapp-private-chat-body ol li.indent{' | |
+ 'padding-left: 1.5em;' | |
+ '}' | |
+ '.talkerapp-private-chat-body ol li.divider{' | |
+ 'padding: 0; line-height: 0; height: 0; border-top: 1px dotted #ccc; margin: 0 .5em;' | |
+ '}' | |
+ '.talkerapp-private-chat-msgbox{' | |
+ 'position: absolute; left: 0; bottom: 0; right: 0; overflow: hidden; height: 48px;' | |
+ '}' | |
+ '.talkerapp-private-chat-msgbox textarea{' | |
+ 'position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; resize: none;' | |
+ '}' | |
+ '.message.me.private{display: none;}' | |
+ '</style>'); | |
$('head').append($style); | |
var chatItemHTML = '<li>' | |
+ '<div class="talker">{talkerNick}:</div>' | |
+ '<div class="msg">{talkerMsg}</div>' | |
+ '</li>'; | |
var chatItemHTML2 = '<li class="indent">' | |
+ '<div class="msg">{talkerMsg}</div>' | |
+ '</li>'; | |
var chatPaneHTML = '<div class="talkerapp-private-chat-pane" data-talker="{talkerID}">' | |
+ '<div class="talkerapp-private-chat-head">{talkerID} <a href="#" class="close">×</a></div>' | |
+ '<div class="talkerapp-private-chat-body">' | |
+ '<ol class="talkerapp-private-chat-list">' | |
+ '</ol>' | |
+ '<div class="talkerapp-private-chat-msgbox">' | |
+ '<textarea></textarea>' | |
+ '</div>' | |
+ '</div>' | |
+ '</div>'; | |
var chatDividerHTML = '<li class="divider"></li>'; | |
var talkers = []; | |
var me = Talker.currentUser.name; | |
var paneWidth = 240; | |
var paneSpace = 10; | |
var url_expression = /(https?:\/\/|www\.)[^\s<]*/gi; | |
var protocol_expression = /^(http|https|ftp|ftps|ssh|irc|mms|file|about|mailto|xmpp):\/\//; | |
var formatMsg = function(msg){ | |
if (!msg) return; | |
return msg.replace(/"/g, '"') | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(url_expression, function(l){ | |
return '<a href="' | |
+ (!l.match(protocol_expression) ? 'http://' : '') + l | |
+ '" target="_blank">' + l + '</a>'; | |
}); | |
}; | |
var insertMsg = function(id, talker, msg){ | |
if (id == me) return; // don't talk to yourself, ok? | |
var inTalkers = ($.inArray(id, talkers) != -1); | |
var pos = talkers.length; | |
if (!inTalkers){ | |
talkers.push(id); | |
var html = $.nano(chatPaneHTML, { | |
talkerID: id | |
}); | |
$('body').append(html); | |
} | |
var pane = $('.talkerapp-private-chat-pane[data-talker=' + id + ']'); | |
if (!inTalkers) pane.css('right', paneSpace+(paneSpace+paneWidth)*pos); | |
if (pane.hasClass('collapsed')){ | |
pane.addClass('new-msg'); | |
} else { | |
pane.find('.talkerapp-private-chat-msgbox textarea').focus(); | |
} | |
if (!msg) return; | |
var lastTalker = pane.data('lastTalker'); | |
var html = $.nano((lastTalker != talker) ? chatItemHTML : chatItemHTML2, { | |
talkerNick: talker, | |
talkerMsg: formatMsg(msg) | |
}); | |
pane.find('ol').append(html); | |
pane.data('lastTalker', talker); | |
// scroll to bottom | |
var body = pane.find('.talkerapp-private-chat-body ol')[0]; | |
body.scrollTop = body.scrollHeight; | |
}; | |
// Received private messages | |
plugin.onMessageReceived = function(e){ | |
if (!e || !e.private || e.type != 'message') return; | |
var talker = e.user.name; | |
var msg = e.content; | |
insertMsg(talker, talker, msg); | |
return false; | |
}; | |
// Send private messages | |
plugin.onMessageSent = function(e){ | |
if (!e || e.type != 'command' || e.command != 'msg' || !e.args || e.args.length <= 1) return; | |
var args = e.args.slice(); | |
var talker = args[0].replace(/^@/, ''); | |
args.shift(); | |
var msg = args.join(' '); | |
insertMsg(talker, me, msg); | |
return false; | |
} | |
var offline = false; | |
var disableTextareas = function(){ | |
var users = _.map(Talker.getRoomUsers(), function(user){ | |
return user.name; | |
}); | |
var offUsers = []; | |
for (var i=0, l=talkers.length; i<l; i++){ | |
if ($.inArray(talkers[i], users) == -1) offUsers.push(talkers[i]); | |
} | |
var panes = $('.talkerapp-private-chat-pane'); | |
panes.find('textarea').removeAttr('disabled'); | |
for (var j=0, l=offUsers.length; j<l; j++){ | |
panes.filter('[data-talker=' + offUsers[j] + ']').find('textarea').attr('disabled', true); | |
} | |
}; | |
plugin.onOpen = function(){ | |
offline = false; | |
disableTextareas(); | |
}; | |
plugin.onClose = function(){ | |
offline = true; | |
} | |
plugin.onJoin = plugin.onLeave = disableTextareas; | |
$('.talkerapp-private-chat-head').live('click', function(){ | |
var pane = $(this).parent('.talkerapp-private-chat-pane'); | |
if (pane.hasClass('collapsed')){ | |
pane.removeClass('collapsed'); | |
pane.removeClass('new-msg'); | |
pane.find('.talkerapp-private-chat-msgbox textarea').focus(); | |
} else { | |
pane.addClass('collapsed'); | |
var ol = pane.find('ol'); | |
var divider = ol.find('li.divider'); | |
ol.append(divider.length ? divider : chatDividerHTML); | |
} | |
}); | |
$('.talkerapp-private-chat-msgbox textarea').live('keydown', function(e){ | |
e.stopPropagation(); | |
var textarea = $(this); | |
if (e.keyCode == 13){ // enter | |
e.preventDefault(); | |
var val = $.trim(textarea.val()); | |
if (val !== ''){ | |
var talker = textarea.parents('.talkerapp-private-chat-pane').attr('data-talker'); | |
Talker.trigger('MessageSend', { | |
type: 'message', | |
content: '/msg ' + talker + ' ' + val | |
}); | |
textarea.val('').focus(); | |
} | |
} | |
}); | |
$('#people li').live('dblclick', function(){ | |
var el = $(this); | |
var talker = $.trim(el.text()); | |
insertMsg(talker, me, null); | |
}); | |
$('.talkerapp-private-chat-head .close').live('click', function(){ | |
if (confirm('Are you sure? All chat messages are NOT saved.')){ | |
var el = $(this); | |
var pane = el.parents('.talkerapp-private-chat-pane'); | |
var talker = pane.attr('data-talker'); | |
for (var i = talkers.length; i--; i){ | |
if (talkers[i] === talker) talkers.splice(i, 1); | |
} | |
pane.nextAll('.talkerapp-private-chat-pane').each(function(){ | |
$(this).animate({ | |
right: '-=' + (paneWidth+paneSpace) | |
}); | |
}); | |
pane.remove(); | |
} | |
return false; | |
}) | |
$('.talkerapp-private-chat-pane textarea').live('mousedown keydown click', function(){ | |
if (offline) return false; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment