diff options
Diffstat (limited to 'static/js/pichat.js')
| -rw-r--r--[-rwxr-xr-x] | static/js/pichat.js | 381 |
1 files changed, 316 insertions, 65 deletions
diff --git a/static/js/pichat.js b/static/js/pichat.js index a13b572..111f574 100755..100644 --- a/static/js/pichat.js +++ b/static/js/pichat.js @@ -1,30 +1,58 @@ var cache = {} var PendingMessages = {} +var MessageContentCache = {} var MaxImagePosts = 40 // Utils -// use e.g. "backgroundColor" not "background-color" -function isCSSPropertySupported(prop){ - return prop in document.body.style; +/*Object.size = function(obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) size++; + } + return size; +};*/ + +isEmptyObject = function(obj) { + for (key in obj) { + if (obj.hasOwnProperty(key)) return false; + } + return true } + +function isCSSPropertySupported(prop){ return prop in document.body.style } + function escapeHtml(txt) { if (!txt) { return ""; } else { return $("<span>").text(txt).html(); } } +URLRegex = /((\b(http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; +PicRegex = /\.(jpg|jpeg|png|gif|bmp)$/i; + +function getImagesAsArray(text) { + var imgs = [] + var urls = text.match(URLRegex) + if (urls === null) return imgs + for (var i = 0; i<urls.length; i++){ + var url = urls[i] + var urlWithoutParams = url.replace(/\?.*$/i, ""); + if (PicRegex.test(urlWithoutParams)) + imgs.push(url) + } + return imgs +} + function linkify(text) { LastMsgContainsImage = false - var URLRegex = /((\b(http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; return text.replace(URLRegex, linkReplace); } // durty hack to use a global to check this... but otherwise i'd have to rewrite the String.replace function? :/ var LastMsgContainsImage = false function linkReplace(url) { - var PicRegex = /\.(jpg|jpeg|png|gif|bmp)$/i; var urlWithoutParams = url.replace(/\?.*$/i, ""); if (url.indexOf('http://') == 0 || url.indexOf('https://') == 0 || url.indexOf('ftp://') == 0) @@ -42,12 +70,10 @@ function linkReplace(url) { function linkifyWithoutImage(text) { LastMsgContainsImage = false - var URLRegex = /((\b(http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; return text.replace(URLRegex, linkReplaceWithoutImage); } function linkReplaceWithoutImage(url){ - var PicRegex = /\.(jpg|jpeg|png|gif|bmp)$/i; var urlWithoutParams = url.replace(/\?.*$/i, ""); linkUrl = url.indexOf('http://') == 0 ? url : 'http://' + url; @@ -80,8 +106,10 @@ function buildMessageDiv(msg, isLoading) { var msgId = !isLoading ? 'id="message-' + msg.msg_id + '"' : ''; var loadingClass = isLoading ? ' loading' : ''; var containsImageClass = LastMsgContainsImage ? ' contains-image' : ''; - return '<div class="msgDiv ' + loadingClass + containsImageClass + '" ' + msgId + '>' - + '<b><a href="/u/' + nick + ' ">' + nick + '</a>: </b>' + return '<div class="msgDiv dump ' + loadingClass + containsImageClass + '" ' + msgId + '>' + + '<span class="nick"><b><a href="/u/' + nick + ' ">' + nick + '</a></b>' + + ' <img src="'+Imgs.chatThumbDot+'" class="thumb chat-thumb" onclick="Tag.favorite(this)"> ' + + '</span>' + buildMsgContent(msg.content) + '</div>'; } @@ -130,7 +158,7 @@ function submitMessage() { var content = $.trim($('#msgInput').val()); $('#msgInput').val(''); if (content == '') { return; } - if (content.length > 1000) { + if (content.length > 1337) { alert("POST TOO LONG DUDE!"); return; } // this shouldn't just be client side :V @@ -193,18 +221,19 @@ function flattenUserJson(users) { } function updateUI(msgs, users) { - if (window['growlize'] && msgs && msgs.length > 0) { - $.map(msgs, buildGrowlDataAndPopDatShit) - } else if (msgs && msgs.length > 0) { - addNewMessages(msgs); - } - if (users !== null) { - var flattened = flattenUserJson(users); - if (!('userlist' in cache) || flattened != cache.userlist) { - $("#userList").html($.map(users.sort(sortUsersByAlpha), buildUserDiv).join('')); - } - cache.userlist = flattened - } + + if (window['growlize'] && msgs && msgs.length > 0) { + $.map(msgs, buildGrowlDataAndPopDatShit) + } else if (msgs && msgs.length > 0) { + addNewMessages(msgs); + } + if (users !== null) { + var flattened = flattenUserJson(users); + if (!('userlist' in cache) || flattened != cache.userlist) { + $("#userList").html($.map(users.sort(sortUsersByAlpha), buildUserDiv).join('')); + } + cache.userlist = flattened + } } function sortUsersByAlpha(a, b){ @@ -248,6 +277,9 @@ function refresh() { var onSuccess = function(json) { try { Timestamp = json.timestamp; + + $.map(json.messages, function(msg){ MessageContentCache[msg.msg_id.toString()] = msg.content }) + var messages = $.grep( json.messages, function(m) { return !isDuplicateMessage(m) }); @@ -285,16 +317,23 @@ function refresh() { } function initChat() { - $('.msgDiv .content').each(function() { - var t = $(this); - t.html(buildMsgContent(t.text())); + $('.oldmsg').each(function() { + var dump = $(this); + var content = dump.find(".content") + MessageContentCache[dump.attr("id").substr(8)] = content.text() + content.html(buildMsgContent(content.text())); }); $('#msgInput').keyup(ifEnter(submitMessage)); $('#msgSubmit').click(submitMessage); + $('#palette-button').click(paletteToggle); messageList = $("#messageList")[0] + if (!isEmptyObject(RawFavs)) paletteButtonShow() + + initChatThumb() + scrollToEnd() scrollWatcher() @@ -372,6 +411,7 @@ function initProfile() { var t = $(this); t.html(buildMsgContent(t.text())); }); + initLogThumb() }; function initLog() { @@ -379,10 +419,154 @@ function initLog() { var t = $(this); t.html(buildMsgContent(t.text())); }); + initLogThumb(); +} + +// todo: preload these. also, look into image sprites (no go on animating their sizes tho) +Imgs = { + "chatThumb": "/static/img/thumbs/color.right.gif", + "chatThumbBig": "/static/img/thumbs/color.right.4x.gif", + "chatThumbOff": "/static/img/thumbs/bw.right.gif", + "chatThumbDot": "/static/img/thumbs/pink.circle.gif", + "logThumb": "/static/img/thumbs/color.left.gif", + "logThumbBig": "/static/img/thumbs/color.left.4x.gif", + "logThumbOff": "/static/img/thumbs/bw.left.gif" +} + +Anim = { + "chatThumbBig": {"width": "56px", "height": "60px", "right": "-35px", "bottom": "-10px"}, + "chatThumbTiny": {"width": "8px", "height": "8px", "right": "8px", "bottom": "8px"}, + "chatThumb": {"width": "16px", "height": "16px", "right": "4px", "bottom": "4px"}, + "logThumb": {"width": "16px", "height": "16px", "marginLeft": "0px", "marginTop": "0px"}, + "logThumbBig": {"width": "56px", "height": "60px", "marginLeft": "-40px", "marginTop": "-27px"} +} + +// jesus this logic is ugly +function initLogThumb(){ + $(".buttons .thumb").bind('mouseover mouseout', + function(e) { + var favorited = $(this).parents(".dump").hasClass("favorite") ? true : false; + if (e.type == "mouseover") { + if (favorited) { + $(this).attr("src", Imgs.logThumbOff); + } else { + $(this).attr("src", Imgs.logThumbBig); + $(this).stop().animate(Anim.logThumbBig, 'fast'); + } + } else { // mouseout + if (favorited) { + $(this).attr("src", Imgs.logThumb); + $(this).stop().animate(Anim.logThumb, 'fast'); + } else { + $(this).attr("src", Imgs.logThumbOff); + $(this).stop().animate(Anim.logThumb, 'fast'); + } + } + }) +} + +function initChatThumb(){ + + $(".chat-thumb").live('mouseover mouseout', + function(e) { + var favorited = $(this).parents(".dump").hasClass("favorite") ? true : false; + if (e.type == "mouseover") { + if (favorited) { + $(this).attr("src", Imgs.chatThumbOff); + } else { + $(this).attr("src", Imgs.chatThumbBig); + $(this).stop().animate(Anim.chatThumbBig, 'fast') + } + } else { // mouseout + if (favorited) { + $(this).attr("src", Imgs.chatThumb); + $(this).stop().animate(Anim.chatThumb, 'fast'); + } else { + $(this).stop().animate(Anim.chatThumbTiny, 'fast', 'swing', + function(){ + $(this).attr("src", Imgs.chatThumbDot) + $(this).animate(Anim.chatThumb, 0) + }) + } + } + }) +} + +function paletteButtonHideAnim(){ + $("#msginputrapper").stop().animate({"marginRight": "374px"}, 'fast') + $("#msgSubmit").stop().animate({"right": "260px"}, 'fast') + $("#palette-button").stop().animate({"width": "0px"}, 'fast', 'swing', function(){ $("#palette-button").css("display", "none") }) +} +function paletteButtonHide(){ + $("#msginputrapper").css("marginRight", "374px") + $("#msgSubmit").css("right", "260px") + $("#palette-button").css("width", "0px") + $("#palette-button").css("display", "none") +} +function paletteButtonShowAnim(){ + $("#msginputrapper").stop().animate({"marginRight": "415px"}, 'fast') + $("#msgSubmit").stop().animate({"right": "300px"}, 'fast') + $("#palette-button").css("display", "inline-block") + $("#palette-button").stop().animate({"width": "40px"}, 'fast') +} +function paletteButtonShow(){ + $("#msginputrapper").css("marginRight", "415px") + $("#msgSubmit").css("right", "300px") + $("#palette-button").css("display", "inline-block") + $("#palette-button").css("width", "40px") +} + +function paletteToChat(img){ + var chatText = $("#msgInput").val() + if (chatText.length && chatText[chatText.length - 1] != " ") + chatText += " " + chatText += $(img).attr("src") + " " + $("#msgInput").val(chatText) + $("#msgInput").focus().val($("#msgInput").val()) //http://stackoverflow.com/questions/1056359/ + paletteHide() +} + +paletteImageCache = false +function paletteBuildImageThumbs(){ + if (paletteImageCache) { + var imgs = paletteImageCache + } else { + var imgs = [] + var dupeFilter = {} + for(fav in RawFavs){ + var parsedImgs = getImagesAsArray(RawFavs[fav]) + for (var i=0; i<parsedImgs.length; i++){ + var img = parsedImgs[i] + if (!dupeFilter[img]) { + imgs.push(img) + dupeFilter[img] = true + } + } + } + paletteImageCache = imgs + } + + for(var i=0; i<imgs.length; i++){ + $("#palette-thumbs").append("<img onclick='paletteToChat(this)' src='"+imgs[i]+"'>") + } +} + +function paletteShow(){ + $("#palette").css("display", "block") + paletteBuildImageThumbs() +} +function paletteHide(){ + $("#palette").css("display", "none") + $("#palette-thumbs").html("") +} + +function paletteToggle(){ + if ($("#palette").css("display") == "none") + paletteShow() + else + paletteHide() } -// TODO -function favoriteImage() {}; function setupUpload(elementId, roomKey) { var onSubmit = function(file, ext) { @@ -504,7 +688,6 @@ function initDirectory() { //big hand stuff // TODO: replace this with simple pointer-events thing. - function initBigHand(id){ var cursorId = "#cursor-big" var cursor = $(cursorId)[0] @@ -570,42 +753,110 @@ function initBigHand(id){ } +// grab message id etc from some element e that's inside a message +function getMessageInfo(e){ + var message = $(e).parents(".dump") + var id = message.attr("id").substr(8) // cut "message-001" to "001" + var nick = message.attr("nick") + var link = "http://dump.fm/p/" + nick + "/" + id + var content = message.find(".linkify") + if (!content.length) content = message.find(".content") + var rawContent = content.html() + var img = content.find("img").attr("src") + var via = "via " + nick + " on dump.fm" + return {"nick": nick, "id": id, "link": encodeURIComponent(link), + "content": rawContent, "img": encodeURIComponent(img), + "via": encodeURIComponent(via)} +} + Share = { - "getMessage": function(button){ - var message = $(button).parents(".logged-dump") - var id = message.attr("id").substr(8) // cut "message-001" to "001" - var nick = message.attr("nick") // cut "/u/timb" to "timb" - var link = "http://dump.fm/p/" + nick + "/" + id - var content = message.find(".linkify") - if (!content.length) content = message.find(".content") - var rawContent = content.html() - var img = content.find("img").attr("src") - var via = "via " + nick + " on dump.fm" - return {"nick": nick, "id": id, "link": encodeURIComponent(link), - "content": content, "img": encodeURIComponent(img), - "via": encodeURIComponent(via)} - }, - "openLink": function(url){ - window.open(url, "_blank") - }, - "facebook": function(button){ - var message = Share.getMessage(button) - var url = "http://www.facebook.com/share.php?u=" + message.img + "&t=" + message.via - Share.openLink(url) - }, - "tumblr": function(button){ - var message = Share.getMessage(button) - var url = "http://www.tumblr.com/share?v=3&u=" + message.img + "&t=" + message.via - Share.openLink(url) - }, - "twitter": function(button){ - var message = Share.getMessage(button) - var url = "http://twitter.com/home?status=" + message.img + encodeURIComponent(" ") + message.via - Share.openLink(url) - }, - "delicious": function(button){ - var message = Share.getMessage(button) - var url = "http://delicious.com/save?url=" + message.img + "&title=" + message.img + "¬es=" + message.via - Share.openLink(url) + "openLink": function(url){ + window.open(url, "_blank") + }, + "facebook": function(button){ + var message = getMessageInfo(button) + var url = "http://www.facebook.com/share.php?u=" + message.img + "&t=" + message.via + Share.openLink(url) + }, + "tumblr": function(button){ + var message = getMessageInfo(button) + var url = "http://www.tumblr.com/share?v=3&u=" + message.img + "&t=" + message.via + Share.openLink(url) + }, + "twitter": function(button){ + var message = getMessageInfo(button) + var url = "http://twitter.com/home?status=" + message.img + encodeURIComponent(" ") + message.via + Share.openLink(url) + }, + "delicious": function(button){ + var message = getMessageInfo(button) + var url = "http://delicious.com/save?url=" + message.img + "&title=" + message.img + "¬es=" + message.via + Share.openLink(url) + } +} + +Tag = { + "favorite": function(button){ + var message = getMessageInfo(button) + var favorited = ($(button).parents(".dump").hasClass("favorite")) ? true : false + if (favorited) { + Tag.rm(message.id, "favorite") + $(button).parents(".dump").removeClass("favorite") + if (RawFavs && RawFavs[message.id]) { + delete RawFavs[message.id] + paletteImageCache = false + } + } else { + Tag.add(message.id, "favorite") + $(button).parents(".dump").addClass("favorite") + if (RawFavs && MessageContentCache[message.id]) { // chat ui stuff + if ($("#palette-button").css("display") == "none") + paletteButtonShowAnim() + RawFavs[message.id] = MessageContentCache[message.id] + paletteImageCache = false + } } -}
\ No newline at end of file + }, + "add": function(message_id, tag){ + Tag.ajax("/cmd/tag/add", {"message_id": message_id, "tag": tag}) + }, + "rm": function(message_id, tag){ + Tag.ajax("/cmd/tag/rm", {"message_id": message_id, "tag": tag}) + }, + "ajax": function(url, data) { + $.ajax({ + "type": 'POST', + "timeout": 5000, + "url": url, + "data": data, + "cache": false + }); + } +} + + +// uhhh todo: move preload stuff into js: +// var nextImage = new Image(); +// nextImage.src = "your-url/newImage.gif"; + +// mAcRoMeDiA sHiT +function MM_swapImgRestore() { //v3.0 + var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc; +} + +function MM_preloadImages() { //v3.0 + var d=document;if(d.images){ if(!d.MM_p) d.MM_p=new Array();var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++) if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}} +} + +function MM_findObj(n, d) { //v4.01 + var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) { + d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);} + if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n]; + for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); + if(!x && d.getElementById) x=d.getElementById(n); return x; +} + +function MM_swapImage() { //v3.0 + var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3) + if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];} +} |
