// twister_actions.js // 2013 Miguel Freitas // // This file contains some twister "actions" like requesting // posts from dht, sending posts, replies. It seems to be a // intermediate layer between twister_io and interface, but // separation is not clearly defined. Perhaps it would be better // to get rid of this file altogether. // global variables var postsPerRefresh = 10; var maxExpandPost = 20; var _hashtagProcessedMap = {}; var _hashtagPendingPosts = []; var autoUpdateHashtag = false; // ---------------- function requestRepliedBefore(postLi) { if(postLi.siblings().length >= maxExpandPost) return; var originalPost = postLi.find(".post-data"); var reply_n = originalPost.attr('data-replied-to-screen-name'); var reply_k = originalPost.attr('data-replied-to-id'); if( reply_n != undefined && reply_k != undefined ) { dhtget( reply_n, "post" + reply_k, "s", function(postLi, postFromJson) { var newStreamPost = postToElem(postFromJson, "related"); newStreamPost.hide(); postLi.before(newStreamPost); newStreamPost.slideDown("fast"); $.MAL.relatedPostLoaded(); requestRepliedBefore(newStreamPost); }, postLi); } } function requestRepliesAfter(postLi) { if(postLi.siblings().length >= maxExpandPost) return; var originalPost = postLi.find(".post-data"); var original_n = originalPost.attr('data-screen-name'); var original_k = originalPost.attr('data-id'); if( original_n != undefined && original_k != undefined ) { dhtget( original_n, "replies" + original_k, "m", function(postLi, postsFromJson) { for( var i = 0; i < postsFromJson.length; i++) { var newStreamPost = postToElem(postsFromJson[i], "related"); newStreamPost.hide(); postLi.after(newStreamPost); newStreamPost.slideDown("fast"); } $.MAL.relatedPostLoaded(); }, postLi); } } function requestRTs(postLi) { var originalPost = postLi.find(".post-data"); var original_n = originalPost.attr('data-screen-name'); var original_k = originalPost.attr('data-id'); if( original_n != undefined && original_k != undefined ) { dhtget( original_n, "rts" + original_k, "m", function(originalPost, postsFromJson) { if( postsFromJson.length ) { var statCountValue = originalPost.find(".stat-count-value"); statCountValue.text( postsFromJson.length ); var avatarRow = originalPost.find(".avatar-row"); avatarRow.empty(); for( var i = 0; i < postsFromJson.length && i < 8; i++) { var n = postsFromJson[i]["userpost"]["n"]; var elemUser = $("#avatar-row-template").clone(true); elemUser.removeAttr('id'); elemUser.attr('href',$.MAL.userUrl(n)); getFullname(n,elemUser.find(".user-name-tooltip")); getAvatar(n,elemUser.find(".size24")); avatarRow.append( elemUser ); } originalPost.find(".post-stats").slideDown("fast"); } }, originalPost); } } function requestPostRecursively(containerToAppend,username,resource,count) { dhtget( username, resource, "s", function(args, postFromJson) { if( postFromJson ) { var newStreamPost = postToElem(postFromJson, "original"); newStreamPost.hide(); args.containerToAppend.append( newStreamPost ); newStreamPost.slideDown("fast"); $.MAL.postboardLoaded(); if( args.count > 1 ) { var userpost = postFromJson["userpost"]; var n = userpost["n"]; var lastk = userpost["lastk"]; if( lastk == undefined ) lastk = userpost["k"] - 1; // not true with directmsgs in stream requestPostRecursively(args.containerToAppend, n, "post"+lastk, count-1); } } }, {containerToAppend:containerToAppend, count:count} ); } function newPostMsg(msg, $postOrig) { if( lastPostId != undefined ) { var params = [defaultScreenName, lastPostId + 1, msg] if( $postOrig.length ) { params.push($postOrig.attr('data-screen-name')); params.push(parseInt($postOrig.attr('data-id'))); } twisterRpc("newpostmsg", params, function(arg, ret) { incLastPostId(); }, null, function(arg, ret) { var msg = ("message" in ret) ? ret.message : ret; alert(polyglot.t("ajax_error", { error: msg })); }, null); } else { alert(polyglot.t("Internal error: lastPostId unknown (following yourself may fix!)")); } } function newRtMsg($postOrig) { var content_to_rt = $postOrig.attr('data-content_to_rt'); var content_to_sigrt = $postOrig.attr('data-content_to_sigrt'); var sig_userpost = String(content_to_sigrt); var userpost = $.evalJSON(String(content_to_rt)); var rtObj = { sig_userpost :sig_userpost, userpost : userpost }; if( lastPostId != undefined ) { var params = [defaultScreenName, lastPostId+1, rtObj] twisterRpc("newrtmsg", params, function(arg, ret) { incLastPostId(); }, null, function(arg, ret) { var msg = ("message" in ret) ? ret.message : ret; alert(polyglot.t("ajax_error", { error: msg })); }, null); } else { alert(polyglot.t("Internal error: lastPostId unknown (following yourself may fix!)")); } } function updateProfileData(profileModalContent, username) { //profileModalContent.find("a").attr("href",$.MAL.userUrl(username)); profileModalContent.filter(".profile-card").attr("data-screen-name", username); profileModalContent.find(".profile-screen-name b").text(username); profileModalContent.find("a.follow").attr("href", $.MAL.followUrl(username)); profileModalContent.find("a.direct-messages-with-user").attr("href", $.MAL.dmchatUrl(username)); profileModalContent.find("a.new-post-to").attr("href", $.MAL.newPostToUrl(username)); profileModalContent.find("a.mentions-from-user").attr("href", $.MAL.mentionsUrl(username)); getFullname( username, profileModalContent.find(".profile-name") ); getLocation( username, profileModalContent.find(".profile-location") ); getWebpage( username, profileModalContent.find(".profile-url") ); getBio( username, profileModalContent.find(".profile-bio") ); getAvatar( username, profileModalContent.find(".profile-card-photo") ); getPostsCount( username, profileModalContent.find(".posts-count") ); getFollowers( username, profileModalContent.find(".followers-count") ); getNumFollowing( username, profileModalContent.find(".following-count") ); profileModalContent.find(".following-count").parent().attr("href", $.MAL.followingUrl(username)); requestPostRecursively(profileModalContent.find(".postboard-posts"),username,"status",10); } function updateFollowingData(followingModalContent, username) { followingModalContent.find(".following-screen-name b").text(username); loadFollowingIntoList( username, $(followingModalContent[1]) ); } function clearHashtagProcessed() { _hashtagProcessedMap = {}; _hashtagPendingPosts = []; } function requestHashtag(postboard,hashtag,resource) { dhtget( hashtag, resource, "m", function(args, data) { processHashtag(args.postboard, args.hashtag, data); }, {postboard:postboard,hashtag:hashtag}, [10000,2000,3]); // use extended timeout parameters (requires twister_core >= 0.9.14) } function processHashtag(postboard, hashtag, data) { if( data ) { for( var i = data.length-1; i >= 0; i-- ) { var userpost = data[i]["userpost"]; var key = userpost["n"] + ";" + userpost["time"]; if( !(key in _hashtagProcessedMap) ) { _hashtagProcessedMap[key] = true; _hashtagPendingPosts.push(data[i]); } } if( _hashtagPendingPosts.length ) { if( !postboard.children().length || autoUpdateHashtag ) { displayHashtagPending(postboard); } else { var newTweetsBar = postboard.closest("div").find(".postboard-news"); newTweetsBar.text(polyglot.t("new_posts", _hashtagPendingPosts.length)); newTweetsBar.fadeIn("slow"); } } } } function displayHashtagPending(postboard) { for( var i = 0; i < _hashtagPendingPosts.length; i++ ) { var streamPost = postToElem(_hashtagPendingPosts[i], "original"); var timePost = _hashtagPendingPosts[i]["userpost"]["time"]; var streamItems = postboard.children(); if( streamItems.length == 0) { postboard.prepend( streamPost ); } else { var j = 0; for( j = 0; j < streamItems.length; j++) { var streamItem = streamItems.eq(j); var timeItem = streamItem.attr("data-time"); if( timeItem == undefined || timePost > parseInt(timeItem) ) { // this post in stream is older, so post must be inserted above streamItem.before(streamPost); break; } } if( j == streamItems.length ) { postboard.append( streamPost ); } } } $.MAL.postboardLoaded(); _hashtagPendingPosts = []; }