// pichat.js var Nick = null; 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 escapeHtml(txt) { if (!txt) { return "" } else { return $("").text(txt).html(); } } function buildUserDiv(user) { return '
' + escapeHtml(user) + '
'; } // http://stackoverflow.com/questions/37684/replace-url-with-html-links-javascript function linkify(text) { var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi; return text.replace(exp,"$1"); } // 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 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 init() { var onSuccess = function(json) { $('#loadingbox').hide(); Nick = json.nick; $('#nickspan').text(Nick); $('#welcomebar').show(); var msgStr = $.map(json.messages, buildMessageDiv).join(''); $('#messageList').append(msgStr); $("#userList").html($.map(json.users, buildUserDiv).join('')); $('#nickInput, #nickSubmit, #msgInput, #msgSubmit').removeAttr('disabled'); // Delay scrolling by .5 seconds so images can start loading. setTimeout(scrollToBottom, 500, $('#messageList')[0]); setInterval(refresh, 1000); }; var onError = function(resp, textStatus, errorThrown) { alert("Error connecting to chat server!"); }; $.ajax({ type: 'GET', timeout: 5000, url: 'init', cache: false, dataType: 'json', success: onSuccess, error: onError }); $('#msgInput').keyup(ifEnter(submitMessage)); $('#msgSubmit').click(submitMessage); }