// pichat.js
var Nick = null;
function handleJoinError(resp) {
var respText = resp.responseText ? resp.responseText.trim() : false;
if (respText == 'NICK_TAKEN') {
alert("Nick '" + Nick + "' was taken! Please choose another.");
} else if (respText) {
alert("Cannot join! (" + respText + ")");
} else {
alert("Cannot join! Please try again later.");
}
}
function handleMsgError(resp) {
var respText = resp.responseText ? resp.responseText.trim() : false;
if (respText == 'UNKNOWN_USER') {
alert("Can't send message! Please login.");
} else if (respText) {
alert("Cannot send message! (" + respText + ")");
} else {
alert("Cannot send message!");
}
}
function join() {
$('#join, #nick').attr('disabled', true);
$('#loginspinner').show();
Nick = $('#nick').val();
onSuccess = function(json) {
generateChatInterface(json.users, json.messages);
};
onError = function(resp, textStatus, errorThrown) {
$('#join, #nick').attr('disabled', false);
$('#loginspinner').hide();
handleJoinError(resp);
};
$.ajax({
type: 'GET',
timeout: 5000,
url: 'join',
data: {'nick': Nick },
cache: false,
dataType: 'json',
success: onSuccess,
error: onError
});
}
function buildUserDiv(user) {
return '
' + user + '
';
}
// http://snippets.dzone.com/posts/show/6995
var URLRegex = /((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i;
function buildMessageDiv(msg) {
var match = URLRegex.exec(msg.content)
if (match) {
return '' + msg.nick + ': '
+ '
'
+ '
';
} else {
return '' + msg.nick + ": "
+ msg.content + "
";
}
}
function buildChatInterface(users, messages) {
var userList = ''
+ $.map(users, buildUserDiv).join('') + '
';
var messageList = '';
return 'Pichat
' + userList + messageList + '
';
}
function submitMessage() {
var content = $('#msgInput').val();
var msg = { 'nick': Nick, 'content': content, 'timestamp': new Date() };
if (content == '') { return; }
var shouldScroll = isScrolledToBottom($('#messageList')[0]);
$('#messageList').append($(buildMessageDiv(msg)));
$('#msgInput').val('');
if (shouldScroll) {
scrollToBottom($('#messageList')[0]);
}
var onSuccess = function() {};
var onError = function(resp, textStatus, errorThrown) {
handleMsgError(resp);
};
$.ajax({
type: 'GET',
timeout: 5000,
url: 'msg',
data: {'content': content },
cache: false,
dataType: 'json',
success: onSuccess,
error: onError
});
}
function ifEnter(fn) {
return function(e) {
if (e.keyCode == 13) { fn(); }
};
}
function isScrolledToBottom(div) {
return Math.abs(div.scrollTop - (div.scrollHeight - div.offsetHeight)) <= 3;
}
function scrollToBottom(div) {
div.scrollTop = div.scrollHeight;
}
function refresh() {
var onSuccess = function(json) {
if (json.messages.length == 0) {
return;
}
var shouldScroll = isScrolledToBottom($('#messageList')[0]);
// Ignore our own messages
var filterFunc = function(m) { return m.nick != Nick };
var msgStr = $.map($.grep(json.messages, filterFunc),
buildMessageDiv).join('');
$('#messageList').append(msgStr);
if (shouldScroll) {
scrollToBottom($('#messageList')[0]);
}
};
var onError = function(resp, textStatus, errorThrown) {};
$.ajax({
type: 'GET',
timeout: 5000,
url: 'refresh',
cache: false,
dataType: 'json',
success: onSuccess,
error: onError
});
}
function generateChatInterface(users, messages) {
$('#content').html(buildChatInterface(users, messages));
$('#msgInput').keyup(ifEnter(submitMessage));
$('#msgSubmit').click(submitMessage);
setInterval(refresh, 1000);
}