// 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 = '
' + '
' + $.map(messages, buildMessageDiv).join('') + '
' + '
' + '' + '' + '
' + '
'; 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); }