twister HTML + Javascript User Interface
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

364 lines
14 KiB

// 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 = 8;
var maxExpandPostTop = 4;
var _hashtagProcessedMap = {};
var _hashtagPendingPosts = [];
var autoUpdateHashtag = false;
// ----------------
function requestRepliedBefore(postLi)
{
if(postLi.siblings().length >= maxExpandPostTop)
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($.MAL.getExpandedPostsCount(postLi) >= 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", $.MAL.reqRepAfterCB, postLi);
}
}
function getTopPostOfConversation(postLi, post, postboard) {
var reply_n;
var reply_k;
if (post && typeof(post) !== 'undefined' && "reply" in post["userpost"]) {
reply_k = post["userpost"]["reply"]["k"];
reply_n = post["userpost"]["reply"]["n"];
} else if (postLi && typeof(postLi) !== 'undefined') {
var originalPost = postLi.find(".post-data");
reply_n = originalPost.attr('data-replied-to-screen-name');
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) {
getTopPostOfConversation(null, postFromJson, postboard);
}, postLi);
} else {
var newStreamPost;
if (post)
newStreamPost = postToElem(post, "related");
else {
newStreamPost = postLi.clone(true);
newStreamPost.removeClass('original');
newStreamPost.addClass('related');
newStreamPost.find('.expanded-content').hide();
newStreamPost.find('.show-more').hide();
}
requestRepliesAfterAll(newStreamPost);
newStreamPost.find('.post-expand').remove();
newStreamPost.unbind('click');
newStreamPost.hide();
postboard.append(newStreamPost);
newStreamPost.slideDown("fast");
}
}
function requestRepliesAfterAll(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, "replies" + original_k, "m", $.MAL.reqRepAfterCB, 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 appendPostToContainer(postFromJson, containerToAppend)
{
var newStreamPost = postToElem(postFromJson, "original");
newStreamPost.hide();
containerToAppend.append( newStreamPost );
newStreamPost.slideDown("fast");
$.MAL.postboardLoaded();
}
var profilePostsLoading = false;
function requestPostRecursively(containerToAppend,username,resource,count,useGetposts)
{
var max_id = -1;
if( !resource ) {
var streamItems = containerToAppend.children();
if( streamItems.length != 0 ) {
var lastItem = streamItems.eq(streamItems.length-1);
resource = "post" + lastItem.find(".post-data").attr("data-lastk");
max_id = parseInt(lastItem.find(".post-data").attr("data-id"))-1;
}
}
profilePostsLoading = true;
if( useGetposts ) {
req = {username: username}
if( max_id != -1 ) {
req.max_id = max_id;
}
twisterRpc("getposts", [count,[req]],
function(args, posts) {
for( var i = 0; i < posts.length; i++ ) {
appendPostToContainer(posts[i],args.containerToAppend);
}
profilePostsLoading = false;
}, {containerToAppend:containerToAppend},
function(args, ret) {
profilePostsLoading = false;
}, {});
} else {
dhtget( username, resource, "s",
function(args, postFromJson) {
if( postFromJson ) {
appendPostToContainer(postFromJson,args.containerToAppend);
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);
} else {
profilePostsLoading = false;
args.containerToAppend.scroll();
}
} else {
profilePostsLoading = false;
}
}, {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") );
getTox( username, profileModalContent.find(".profile-tox") );
getBitmessage( username, profileModalContent.find(".profile-bitmessage") );
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") );
getWhoFollows ( username, profileModalContent.find(".who-follow") );
profileModalContent.find(".following-count").parent().attr("href", $.MAL.followingUrl(username));
var postsView = profileModalContent.find(".postboard-posts");
// try using getposts first. fallback to dht.
twisterRpc("getposts", [1,[{username: username}]],
function(args, posts) {
updateProfilePosts(postsView, username, posts.length);
}, {},
function(args, ret) {
updateProfilePosts(postsView, username, false);
}, {});
}
function updateProfilePosts(postsView, username, useGetposts) {
requestPostRecursively(postsView,username,"status",postsPerRefresh, useGetposts);
postsView.scroll(function(){
if (!profilePostsLoading) {
var $this = $(this);
if ($this.scrollTop() >= this.scrollHeight - $this.height() - 20) {
requestPostRecursively($this,username,"",postsPerRefresh, useGetposts);
}
}
});
}
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, timeoutArgs) {
dhtget( hashtag, resource, "m",
function(args, data) {
processHashtag(args.postboard, args.hashtag, data);
}, {postboard:postboard,hashtag:hashtag},
timeoutArgs);
}
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(!postboard.children().length && !_hashtagPendingPosts.length && hashtag != defaultScreenName)
postboard.closest("div").find(".no-posts-found-message").show();
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");
}
postboard.closest("div").find(".no-posts-found-message").hide();
}
}
}
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 = [];
}