// 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 escapeHtml(txt) { return $("").text(txt).html(); } function buildUserDiv(user) { return '
' + escapeHtml(user) + '
'; } // http://rickyrosario.com/blog/converting-a-url-into-a-link-in-javascript-linkify-function function linkify(text){ if (text) { text = text.replace( /((https?\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function(url){ var full_url = url; if (!full_url.match('^https?:\/\/')) { full_url = 'http://' + full_url; } return '' + url + ''; } ); } return text; } // http://snippets.dzone.com/posts/show/6995 var URLRegex = /((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i; var PicRegex = /\.(jpg|jpeg|png|gif|bmp)$/i; function buildMessageDiv(msg) { function buildContent(content) { var match = URLRegex.exec(content) if (match && PicRegex.test(match[0])) { return '' + ''; } else { return linkify(escapeHtml(msg.content)); } } return '
' + escapeHtml(msg.nick) + ': ' + buildContent(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) { 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]); } } $("#userList").html($.map(json.users, buildUserDiv).join('')); }; 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); }