|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var lastk,
|
|
|
|
profilePostsLoading = false;
|
|
|
|
|
|
|
|
function requestPostRecursively(containerToAppend,username,resource,count)
|
|
|
|
{
|
|
|
|
profilePostsLoading = true;
|
|
|
|
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();
|
|
|
|
|
|
|
|
var userpost = postFromJson["userpost"];
|
|
|
|
var n = userpost["n"];
|
|
|
|
lastk = userpost["lastk"];
|
|
|
|
if( lastk == undefined )
|
|
|
|
lastk = userpost["k"] - 1; // not true with directmsgs in stream
|
|
|
|
|
|
|
|
if( args.count > 1 ) {
|
|
|
|
requestPostRecursively(args.containerToAppend, n, "post"+lastk, count-1);
|
|
|
|
} 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") );
|
|
|
|
|
|
|
|
profileModalContent.find(".following-count").parent().attr("href", $.MAL.followingUrl(username));
|
|
|
|
|
|
|
|
var postsView = profileModalContent.find(".postboard-posts");
|
|
|
|
requestPostRecursively(postsView,username,"status",20);
|
|
|
|
postsView.scroll(function(){
|
|
|
|
if (!profilePostsLoading) {
|
|
|
|
var $this = $(this);
|
|
|
|
if ($this.scrollTop() >= this.scrollHeight - $this.height() - 20) {
|
|
|
|
requestPostRecursively($this,username,"post"+lastk,20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
if(/[a-z]/i.test(hashtag))hashtag = hashtag.toLowerCase(); //hed//fix english hashtag case dependency bug
|
|
|
|
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(!postboard.children().length&&!_hashtagPendingPosts.length)
|
|
|
|
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 = [];
|
|
|
|
}
|
|
|
|
|