// 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 setNick(nick) { Nick = nick; $('#nickspan').text(nick); $('#welcomebar').show(); $('#msgInput, #msgSubmit').removeAttr('disabled'); $('#msgInput').keyup(ifEnter(submitMessage)); $('#msgSubmit').click(submitMessage); } 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 login() { var nick = $('#nickInput').val(); var password = $('#passwordInput').val(); var hash = hex_sha1(nick + '$' + password + '$dumpfm'); var onSuccess = function(json) { $('#loginbar').hide(); setNick(nick); }; var onError = function(resp, textStatus, errorThrown) { alert("Error logging in!"); }; $.ajax({ type: 'GET', timeout: 5000, url: 'login', data: {'nick': nick, 'hash': hash }, cache: false, dataType: 'json', success: onSuccess, error: onError }); }; function isScrolledToBottom(div) { return Math.abs(div.scrollTop - (div.scrollHeight - div.offsetHeight)) <= 3; } function scrollToBottom(div) { div.scrollTop = div.scrollHeight; } function updateUI(json, initialUpdate) { if (json.messages.length > 0) { if (initialUpdate) { var messages = json.messages; } else { // Our own messages have already been displayed. var filterFunc = function(m) { return m.nick != Nick }; var messages = $.grep(json.messages, filterFunc); } var msgStr = $.map(messages, buildMessageDiv).join(''); var wasScrolledToBottom = isScrolledToBottom($('#messageList')[0]); $('#messageList').append(msgStr); if (initialUpdate || wasScrolledToBottom) { // Delay scrolling by .5 seconds so images can start loading. setTimeout(scrollToBottom, 500, $('#messageList')[0]); } } $("#userList").html($.map(json.users, buildUserDiv).join('')); } function refresh() { var onSuccess = function(json) { updateUI(json, false); setTimeout(refresh, 1000); }; var onError = function(resp, textStatus, errorThrown) { setTimeout(refresh, 1000); }; $.ajax({ type: 'GET', timeout: 5000, url: 'refresh', cache: false, dataType: 'json', success: onSuccess, error: onError }); } function init() { var onSuccess = function(json) { if (json.nick) { setNick(json.nick); } else { $('#loginbar').show(); $('#passwordInput').keyup(ifEnter(login)); $('#loginSubmit').click(login); } updateUI(json, true); setTimeout(refresh, 1000); }; var onError = function(resp, textStatus, errorThrown) { alert("Error initializing!"); }; $.ajax({ type: 'GET', timeout: 5000, url: 'init', cache: false, dataType: 'json', success: onSuccess, error: onError }); }