Browse Source

tune DMS and mentions processing, add DMs caching to localStorage

readme-update
Simon Grim 7 years ago
parent
commit
0133ffd486
  1. 15
      js/interface_common.js
  2. 60
      js/tmobile.js
  3. 135
      js/twister_actions.js
  4. 186
      js/twister_directmsg.js
  5. 356
      js/twister_newmsgs.js
  6. 17
      js/twister_timeline.js

15
js/interface_common.js

@ -672,17 +672,10 @@ function openMentionsModalHandler(peerAlias) {
}); });
var req = queryStart(modal.content.find('.postboard-posts'), peerAlias, 'mention'); var req = queryStart(modal.content.find('.postboard-posts'), peerAlias, 'mention');
modal.content.find('.postboard-news') modal.content.find('.postboard-news').on('click', {req: req}, handleClickDisplayPendingTwists);
.on('click',
{req: req, cbFunc: (peerAlias === defaultScreenName) ? resetMentionsCount : ''},
handleClickDisplayPendingTwists
)
;
if (peerAlias === defaultScreenName) { if (peerAlias === defaultScreenName)
modal.content.on('scroll', handleMentionsModalScroll); modal.content.on('scroll', handleMentionsModalScroll);
resetMentionsCount();
}
} }
function openFollowersModal(peerAlias) { function openFollowersModal(peerAlias) {
@ -943,9 +936,9 @@ function addToCommonDMsList(list, targetAlias, message) {
getFullname(targetAlias, item.find('a.post-info-name')); getFullname(targetAlias, item.find('a.post-info-name'));
} }
if (_newDMsPerUser[targetAlias] > 0) if (twister.DMs[targetAlias].lengthNew > 0)
item.addClass('new') item.addClass('new')
.find('.messages-qtd').text(_newDMsPerUser[targetAlias]).show(); .find('.messages-qtd').text(twister.DMs[targetAlias].lengthNew).show();
var items = list.children(); var items = list.children();
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {

60
js/tmobile.js

@ -273,23 +273,37 @@ var router=new $.mobile.Router(
$.mobile.showPageLoadingMsg(); $.mobile.showPageLoadingMsg();
initializeTwister( true, true, function() { initializeTwister( true, true, function() {
$.mobile.showPageLoadingMsg(); $.mobile.showPageLoadingMsg();
requestDMsnippetList($('#directmsg .direct-messages-list')); modalDMsSummaryDraw($('#directmsg .direct-messages-list'));
}); });
}, },
dmchat: function(type,match,ui) { dmchat: function(type,match,ui) {
var params=router.getParams(match[1]); var params=router.getParams(match[1]);
$.mobile.showPageLoadingMsg(); $.mobile.showPageLoadingMsg();
initializeTwister( true, true, function() { initializeTwister( true, true, function() {
var user = params.user; var peerAlias = params.user;
var dmConvo = $('#dmchat .direct-messages-thread'); var board = $('#dmchat .direct-messages-thread').empty();
$("#dmchat .rtitle").text("Chat @" + user);
$('#dmchat .rtitle').text('Chat @' + peerAlias);
$("#dmchat textarea").val(""); $("#dmchat textarea").val("");
dmConvo.html(""); installDMSendClick(peerAlias);
installDMSendClick();
$.mobile.showPageLoadingMsg(); $.mobile.showPageLoadingMsg();
dmChatUser = user;
requestDmConversation(dmConvo,user); tmobileQueryReq = queryStart(board, peerAlias, 'direct', undefined, 2000, {
boardAutoAppend: true,
lastId: 0,
lengthNew: 0,
ready: function (req, peerAlias) {
twister.DMs[peerAlias] = twister.res[req];
},
readyReq: peerAlias,
drawFinish: function (req) {
setTimeout($.MAL.dmConversationLoaded, 200, twister.res[req].board);
},
skidoo: function (req) {
return $.mobile.activePage.attr('id') !== 'dmchat' || req !== tmobileQueryReq;
}
});
}); });
}, },
search: function(type,match,ui) { search: function(type,match,ui) {
@ -390,23 +404,21 @@ function installSubmitClick() {
}); });
} }
function installDMSendClick() { function installDMSendClick(peerAlias) {
var $postSubmit = $(".dm-submit"); $('.dm-submit').off('click').on('click', {peerAlias: peerAlias},
$postSubmit.unbind('click').click(function(e){ function (event) {
e.stopPropagation(); muteEvent(event, true);
e.preventDefault();
var $this = $( this );
var $replyText = $this.closest(".post-area-new").find("textarea");
var $dmConversation = $(".directMessages"); var elemTextArea = $(event.target).closest('.post-area-new').find('textarea');
if (!elemTextArea.val())
return;
var s = encode_utf8($replyText.val()); newDirectMsg(encode_utf8(elemTextArea.val()), event.data.peerAlias);
newDirectMsg(s, dmChatUser); elemTextArea.val('');
$replyText.val(""); }
}); );
} }
function installRetransmitConfirmClick() { function installRetransmitConfirmClick() {
var $postConfirmRt = $(".retransmit-confirm"); var $postConfirmRt = $(".retransmit-confirm");
$postConfirmRt.unbind('click').click(function(e){ $postConfirmRt.unbind('click').click(function(e){
@ -535,15 +547,13 @@ function setupHashtagOrMention(board, query, resource) {
$.mobile.showPageLoadingMsg(); $.mobile.showPageLoadingMsg();
board.empty(); board.empty();
var req = queryStart(board, query, resource, undefined, undefined, { tmobileQueryReq = queryStart(board, query, resource, undefined, undefined, {
boardAutoAppend: true, boardAutoAppend: true,
skidoo: function (req) { skidoo: function (req) {
var curPage = $.mobile.activePage.attr('id'); var curPage = $.mobile.activePage.attr('id');
return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq; return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq;
} }
}); });
tmobileQueryReq = req;
} }
// every 2 seconds do something page specific. // every 2 seconds do something page specific.
@ -565,8 +575,6 @@ function tmobileTick() {
} }
}, {} ); }, {} );
} }
if (curPage === 'dmchat')
requestDmConversation($('#dmchat .direct-messages-thread'), dmChatUser);
} }
$(document).bind('mobileinit', function () { $(document).bind('mobileinit', function () {

135
js/twister_actions.js

@ -436,6 +436,24 @@ function updateProfilePosts(postsView, username, useGetposts) {
}); });
} }
function queryCreateRes(query, resource, extra) {
var req = query + '@' + resource;
twister.res[req] = {
query: query,
resource: resource,
lengthCached: 0,
twists: {
cached: {},
pending: []
}
};
if (extra)
for (i in extra)
twister.res[req][i] = extra[i];
return twister.res[req];
}
function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra) { function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra) {
var req = query + '@' + resource; var req = query + '@' + resource;
@ -444,6 +462,7 @@ function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra)
board: board, board: board,
query: query, query: query,
resource: resource, resource: resource,
lengthCached: 0,
twists: { twists: {
cached: {}, cached: {},
pending: [] pending: []
@ -462,6 +481,15 @@ function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra)
if (twister.res[req].twists.pending.indexOf(i) === -1) if (twister.res[req].twists.pending.indexOf(i) === -1)
twister.res[req].twists.pending.push(i); twister.res[req].twists.pending.push(i);
if (extra) {
if (typeof extra.drawFinish === 'function') {
twister.res[req].drawFinish = extra.drawFinish;
twister.res[req].drawFinishReq = extra.drawFinishReq;
}
if (typeof extra.skidoo === 'function')
twister.res[req].skidoo = extra.skidoo;
}
queryPendingDraw(req); queryPendingDraw(req);
} }
@ -510,27 +538,45 @@ function queryRequest(req) {
} else if (twister.res[req].resource === 'fav') } else if (twister.res[req].resource === 'fav')
twisterRpc('getfavs', [twister.res[req].query, 1000], twisterRpc('getfavs', [twister.res[req].query, 1000],
queryProcess, req); queryProcess, req);
else else if (twister.res[req].resource === 'direct') {
var lengthStandard = 100; // FIXME there may be the gap between .lastId and the lesser twist.id in response greater than 100 (very rare case)
if (twister.res[req].lengthCached < Math.min(twister.res[req].lastId, lengthStandard)
&& !twister.res[req].triedToReCache) {
twister.res[req].triedToReCache = true;
var length = Math.min(twister.res[req].lastId + 1, lengthStandard);
var query = [{username: twister.res[req].query, max_id: twister.res[req].lastId}];
} else
var length = lengthStandard, query = [{username: twister.res[req].query, since_id: twister.res[req].lastId}];
twisterRpc('getdirectmsgs', [defaultScreenName, length, query],
queryProcess, req,
function (req, res) {
console.warn(polyglot.t('ajax_error', {error: (res && res.message) ? res.message : res}));
}
);
} else
dhtget(twister.res[req].query, twister.res[req].resource, 'm', dhtget(twister.res[req].query, twister.res[req].resource, 'm',
queryProcess, req, twister.res[req].timeoutArgs); queryProcess, req, twister.res[req].timeoutArgs);
} }
function queryProcess(req, twists) { function queryProcess(req, res) {
if (!req || !twister.res[req] || !twists || !twists.length) if (!req || !twister.res[req] || typeof res !== 'object' || $.isEmptyObject(res))
return; return;
var lengthNew = 0; var lengthNew = 0;
var lengthPending = twister.res[req].twists.pending.length; var lengthPending = twister.res[req].twists.pending.length;
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName)
lengthNew = queryPendingPushMentions(req, twists); lengthNew = queryPendingPushMentions(req, res);
else if (twister.res[req].resource === 'direct')
lengthNew = queryPendingPushDMs(res);
else else
lengthNew = queryPendingPush(req, twists); lengthNew = queryPendingPush(req, res);
if (typeof twister.res[req].skidoo === 'function' && twister.res[req].skidoo(req)) if (typeof twister.res[req].skidoo === 'function' && twister.res[req].skidoo(req))
return; return;
if (lengthNew) if (lengthNew) {
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) { if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) {
$.MAL.updateNewMentionsUI(twister.res[req].lengthNew); $.MAL.updateNewMentionsUI(twister.res[req].lengthNew);
$.MAL.soundNotifyMentions(); $.MAL.soundNotifyMentions();
@ -550,6 +596,25 @@ function queryProcess(req, twists) {
$.MAL.showMentions(defaultScreenName); $.MAL.showMentions(defaultScreenName);
}).bind({req: req}) }).bind({req: req})
}); });
} else if (twister.res[req].resource === 'direct') {
if (twister.res[req].query[0] !== '*')
$.MAL.updateNewDMsUI(getNewDMsCount());
else
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
$.MAL.soundNotifyDM();
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable')
$.MAL.showDesktopNotification({
body: twister.res[req].query[0] === '*' ?
polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', getNewGroupDMsCount()) + '.'
: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', getNewDMsCount()) + '.',
tag: 'twister_notification_new_DMs',
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: (function () {
focusModalWithElement(twister.res[this.req].board);
}).bind({req: req})
});
// TODO new DMs counters on minimized modals'
} else if (!$.mobile && $.Options.showDesktopNotifPostsModal.val === 'enable' } else if (!$.mobile && $.Options.showDesktopNotifPostsModal.val === 'enable'
&& (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName) && (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName)
&& twister.res[req].board && isModalWithElemExists(twister.res[req].board) && twister.res[req].board && isModalWithElemExists(twister.res[req].board)
@ -559,7 +624,7 @@ function queryProcess(req, twists) {
+ polyglot.t('in search result') + '.', + polyglot.t('in search result') + '.',
tag: 'twister_notification_new_posts_modal', tag: 'twister_notification_new_posts_modal',
timeout: $.Options.showDesktopNotifPostsModalTimer.val, timeout: $.Options.showDesktopNotifPostsModalTimer.val,
funcClick: (function() { funcClick: (function () {
focusModalWithElement(twister.res[this.req].board, focusModalWithElement(twister.res[this.req].board,
function (req) { function (req) {
twister.res[req].board.closest('.postboard') twister.res[req].board.closest('.postboard')
@ -569,6 +634,7 @@ function queryProcess(req, twists) {
); );
}).bind({req: req}) }).bind({req: req})
}); });
}
if (twister.res[req].twists.pending.length > lengthPending) { // there is some twists may be which are not considered new so lengthNew equals zero (mentions thing) if (twister.res[req].twists.pending.length > lengthPending) { // there is some twists may be which are not considered new so lengthNew equals zero (mentions thing)
if (!twister.res[req].board || (!$.mobile && !isModalWithElemExists(twister.res[req].board))) if (!twister.res[req].board || (!$.mobile && !isModalWithElemExists(twister.res[req].board)))
@ -619,6 +685,7 @@ function queryPendingPush(req, twists) {
lengthNew++; lengthNew++;
twister.res[req].twists.cached[j] = twists[i]; twister.res[req].twists.cached[j] = twists[i];
twister.res[req].lengthCached++;
twister.res[req].twists.pending.push(j); twister.res[req].twists.pending.push(j);
} }
} }
@ -627,13 +694,57 @@ function queryPendingPush(req, twists) {
} }
function queryPendingDraw(req) { function queryPendingDraw(req) {
var twists = []; var twists = [], length = 0;
for (var i = 0; i < twister.res[req].twists.pending.length; i++)
twists.push(twister.res[req].twists.cached[twister.res[req].twists.pending[i]]); if (twister.res[req].resource === 'direct') {
for (var j = 0; j < twister.res[req].twists.pending.length; j++) {
var twist = twister.res[req].twists.cached[twister.res[req].twists.pending[j]];
for (var i = 0; i < length; i++)
if (twist.id < twists[i].id) {
twists.splice(i, 0, twist);
break;
}
if (length === twists.length)
twists.push(twist);
length++;
}
attachPostsToStream(twister.res[req].board, twists, false,
function (twist, req) {
return {item: postToElemDM(twist, req.peerAliasLocal, req.peerAliasRemote)
.attr('data-id', twist.id), time: twist.time};
},
{peerAliasLocal: defaultScreenName, peerAliasRemote: twister.res[req].query}
);
resetNewDMsCountForPeer(twister.res[req].query);
} else {
for (var j = 0; j < twister.res[req].twists.pending.length; j++) {
var twist = twister.res[req].twists.cached[twister.res[req].twists.pending[j]];
for (var i = 0; i < length; i++)
if (twist.userpost.time > twists[i].userpost.time) {
twists.splice(i, 0, twist);
break;
}
if (length === twists.length)
twists.push(twist);
attachPostsToStream(twister.res[req].board, twists, false); length++;
}
attachPostsToStream(twister.res[req].board, twists, true,
function (twist) {
return {item: postToElem(twist, 'original'), time: twist.userpost.time};
}
);
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName)
resetMentionsCount();
}
queryPendingClear(req); queryPendingClear(req);
$.MAL.postboardLoaded(); if (typeof twister.res[req].drawFinish === 'function')
twister.res[req].drawFinish(req, twister.res[req].drawFinishReq);
else
$.MAL.postboardLoaded();
} }

186
js/twister_directmsg.js

@ -5,120 +5,6 @@
var _groupMsgInviteToGroupQueue = []; var _groupMsgInviteToGroupQueue = [];
function requestDMsnippetList(elemList, forGroup) {
var followList = [];
for (var i = 0; i < followingUsers.length; i++)
followList.push({username: followingUsers[i]});
for (var i = 0; i < groupChatAliases.length; i++)
followList.push({username: groupChatAliases[i]});
twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList],
processDMsnippet, {elemList: elemList, forGroup: forGroup},
function(req, ret) {console.log('ajax error:' + ret);}, null
);
}
function processDMsnippet(req, DMs) {
req.elemList.empty();
for (var alias in DMs)
if ((req.forGroup && alias[0] === '*') || (!req.forGroup && alias[0] !== '*'))
addToCommonDMsList(req.elemList, alias, DMs[alias][0]);
$.MAL.commonDMsListLoaded();
}
function requestDmConversationModal(postboard, peerAlias) {
if (!isModalWithElemExists(postboard))
return;
requestDmConversation(postboard, peerAlias);
setTimeout(requestDmConversationModal, 1000, postboard, peerAlias);
}
function requestDmConversation(postboard, peerAlias) {
var since_id = undefined;
var oldItems = postboard.children();
if (oldItems.length)
since_id = parseInt(oldItems.eq(oldItems.length - 1).attr('data-id'));
var userDmReq = [{username: peerAlias}];
if (typeof since_id !== 'undefined')
userDmReq[0].since_id = since_id;
var count = 100;
twisterRpc('getdirectmsgs', [defaultScreenName, count, userDmReq],
function(req, ret) {processDmConversation(req.postboard, req.peerAlias, ret);},
{postboard: postboard, peerAlias: peerAlias},
function(req, ret) {
var msg = (ret.message) ? ret.message : ret;
alert(polyglot.t('ajax_error', {error: msg}));
}
);
}
function processDmConversation(stream, peerAlias, posts) {
if (!isModalWithElemExists(stream))
return;
var streamItems = stream.children();
var streamPostsIDs = [];
var newPosts = 0;
for (var i = 0; i < streamItems.length; i++) {
streamPostsIDs.push(parseInt(streamItems.eq(i).attr('data-id')));
}
if (posts[peerAlias] && posts[peerAlias].length) {
for (var i = 0; i < posts[peerAlias].length; i++) {
if (streamPostsIDs.indexOf(posts[peerAlias][i].id) === -1) {
var lastPostID = posts[peerAlias][i].id;
newPosts++;
postToElemDM(posts[peerAlias][i], defaultScreenName, peerAlias)
.attr('data-id', lastPostID)
.appendTo(stream)
;
streamPostsIDs.push(lastPostID);
}
}
$.MAL.dmConversationLoaded(stream);
}
if (newPosts) {
resetNewDMsCountForUser(peerAlias, lastPostID);
if (getHashOfMinimizedModalWithElem(stream)) {
$.MAL.soundNotifyDM();
_newDMsPerUser[peerAlias] += newPosts;
if (peerAlias[0] === '*')
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
else
$.MAL.updateNewDMsUI(getNewDMsCount());
if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifDMs.val === 'enable')
$.MAL.showDesktopNotification({
body: peerAlias[0] === '*' ?
polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newPosts) + '.'
: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newPosts) + '.',
tag: 'twister_notification_new_DMs',
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: (function() {
focusModalWithElement(this.postboard,
function (peerAlias) {
_newDMsPerUser[peerAlias] = 0;
if (peerAlias[0] === '*')
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
else
$.MAL.updateNewDMsUI(getNewDMsCount());
}, this.peerAlias);
}).bind({postboard: stream, peerAlias: peerAlias})
});
// TODO here we need to set new DMs counter on minimized modal button
}
}
}
function directMsgSubmit(e) { function directMsgSubmit(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
@ -161,6 +47,20 @@ function newDirectMsg(msg, peerAlias) {
alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)')); alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)'));
} }
function modalDMsSummaryDraw(elem, group) {
elem.empty();
for (var peerAlias in twister.DMs)
if (group ? peerAlias[0] === '*' : peerAlias[0] !== '*')
for (var j in twister.DMs[peerAlias].twists.cached)
if (twister.DMs[peerAlias].lastId === twister.DMs[peerAlias].twists.cached[j].id) {
addToCommonDMsList(elem, peerAlias, twister.DMs[peerAlias].twists.cached[j]);
break;
}
$.MAL.commonDMsListLoaded();
}
// dispara o modal de direct messages // dispara o modal de direct messages
function openCommonDMsModal() { function openCommonDMsModal() {
if (!defaultScreenName) { if (!defaultScreenName) {
@ -174,19 +74,16 @@ function openCommonDMsModal() {
title: polyglot.t('Direct Messages') title: polyglot.t('Direct Messages')
}); });
requestDMsnippetList(modal.content.find('.direct-messages-list')); modalDMsSummaryDraw(modal.content.find('.direct-messages-list'));
modal.self.find('.mark-all-as-read') modal.self.find('.mark-all-as-read')
.css('display', 'inline') .css('display', 'inline')
.attr('title', polyglot.t('Mark all as read')) .attr('title', polyglot.t('Mark all as read'))
.on('click', function (event) { .on('click', function (event) {
for (var user in _newDMsPerUser) { resetNewDMsCount();
if (user[0] !== '*') var elem = $(event.target).closest('.directMessages').find('.direct-messages-list');
_newDMsPerUser[user] = 0; elem.find('.messages-qtd').hide();
} elem.find('.post.new').removeClass('new');
saveDMsToStorage();
$.MAL.updateNewDMsUI(getNewDMsCount());
$(event.target).closest('.directMessages').find('.direct-messages-list .messages-qtd').hide();
}) })
; ;
} }
@ -210,7 +107,21 @@ function openDmWithUserModal(peerAlias) {
else else
getFullname(peerAlias, modal.self.find('.modal-header h3 span')); getFullname(peerAlias, modal.self.find('.modal-header h3 span'));
requestDmConversationModal(modal.self.find('.direct-messages-thread').empty(), peerAlias); queryStart(modal.content.find('.direct-messages-thread'),
peerAlias, 'direct', undefined, 2000, {
boardAutoAppend: true,
lastId: 0,
lengthNew: 0,
ready: function (req, peerAlias) {
twister.DMs[peerAlias] = twister.res[req];
},
readyReq: peerAlias,
drawFinish: function (req) {
$.MAL.dmConversationLoaded(twister.res[req].board);
}
}
);
modal.content.on('scroll', {req: peerAlias}, handleDMsModalScroll);
$('.dm-form-template').children().clone(true) $('.dm-form-template').children().clone(true)
.addClass('open').appendTo(modal.content).fadeIn('fast') .addClass('open').appendTo(modal.content).fadeIn('fast')
@ -232,19 +143,16 @@ function openGroupMessagesModal(groupAlias) {
modal.content.prepend($('#group-messages-profile-modal-control-template').children().clone(true)); modal.content.prepend($('#group-messages-profile-modal-control-template').children().clone(true));
requestDMsnippetList(modal.content.find('.direct-messages-list'), true); modalDMsSummaryDraw(modal.content.find('.direct-messages-list'), true);
modal.self.find('.mark-all-as-read') modal.self.find('.mark-all-as-read')
.css('display', 'inline') .css('display', 'inline')
.attr('title', polyglot.t('Mark all as read')) .attr('title', polyglot.t('Mark all as read'))
.on('click', function (event) { .on('click', function (event) {
for (var user in _newDMsPerUser) { resetNewDMsCountGroup();
if (user[0] === '*') var elem = $(event.target).closest('.groupMessages').find('.direct-messages-list');
_newDMsPerUser[user] = 0; elem.find('.messages-qtd').hide();
} elem.find('.post.new').removeClass('new');
saveDMsToStorage();
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
$(event.target).closest('.groupMessages').find('.direct-messages-list .messages-qtd').hide();
}) })
; ;
} else { } else {
@ -261,7 +169,21 @@ function openGroupMessagesModal(groupAlias) {
function(req, ret) { function(req, ret) {
if (ret && ret.members.indexOf(defaultScreenName) !== -1) { if (ret && ret.members.indexOf(defaultScreenName) !== -1) {
req.modal.content.append($('.messages-thread-template').children().clone(true)); req.modal.content.append($('.messages-thread-template').children().clone(true));
requestDmConversationModal(req.modal.content.find('.direct-messages-thread'), req.groupAlias); queryStart(req.modal.content.find('.direct-messages-thread'),
req.groupAlias, 'direct', undefined, 2000, {
boardAutoAppend: true,
lastId: 0,
lengthNew: 0,
ready: function (req, peerAlias) {
twister.DMs[peerAlias] = twister.res[req];
},
readyReq: req.groupAlias,
drawFinish: function (req) {
$.MAL.dmConversationLoaded(twister.res[req].board);
}
}
);
modal.content.on('scroll', {req: req.groupAlias}, handleDMsModalScroll);
var control = $('#group-messages-messages-modal-control-template').children().clone(true) var control = $('#group-messages-messages-modal-control-template').children().clone(true)
.appendTo(req.modal.content); .appendTo(req.modal.content);

356
js/twister_newmsgs.js

@ -42,6 +42,7 @@ function loadMentionsFromStorage() {
var j = mentions.twists[i].userpost.n + '/' + mentions.twists[i].userpost.time; var j = mentions.twists[i].userpost.n + '/' + mentions.twists[i].userpost.time;
if (typeof twister.mentions.twists.cached[j] === 'undefined') { if (typeof twister.mentions.twists.cached[j] === 'undefined') {
twister.mentions.twists.cached[j] = mentions.twists[i]; twister.mentions.twists.cached[j] = mentions.twists[i];
twister.mentions.lengthCached++;
if (twister.mentions.twists.cached[j].isNew) if (twister.mentions.twists.cached[j].isNew)
twister.mentions.lengthNew++; twister.mentions.lengthNew++;
@ -61,6 +62,7 @@ function loadMentionsFromStorage() {
var j = mentions[i].data.userpost.n + '/' + mentions[i].mentionTime; var j = mentions[i].data.userpost.n + '/' + mentions[i].mentionTime;
if (typeof twister.mentions.twists.cached[j] === 'undefined') { if (typeof twister.mentions.twists.cached[j] === 'undefined') {
twister.mentions.twists.cached[j] = mentions[i].data; twister.mentions.twists.cached[j] = mentions[i].data;
twister.mentions.lengthCached++;
if (twister.mentions.twists.cached[j].isNew) if (twister.mentions.twists.cached[j].isNew)
twister.mentions.lengthNew++; twister.mentions.lengthNew++;
@ -104,6 +106,7 @@ function queryPendingPushMentions(req, res) {
var j = res[i].userpost.n + '/' + res[i].userpost.time; var j = res[i].userpost.n + '/' + res[i].userpost.time;
if (typeof twister.res[req].twists.cached[j] === 'undefined') { if (typeof twister.res[req].twists.cached[j] === 'undefined') {
twister.res[req].twists.cached[j] = res[i]; twister.res[req].twists.cached[j] = res[i];
twister.res[req].lengthCached++;
twister.res[req].twists.pending.push(j); twister.res[req].twists.pending.push(j);
// mention must be somewhat recent compared to last known one to be considered new // mention must be somewhat recent compared to last known one to be considered new
@ -159,10 +162,10 @@ function handleMentionsModalScroll(event) {
if (elem.scrollTop() >= elem[0].scrollHeight - elem.height() - 50) { if (elem.scrollTop() >= elem[0].scrollHeight - elem.height() - 50) {
twister.mentions.scrollQueryActive = true; twister.mentions.scrollQueryActive = true;
twisterRpc('getmentions', [twister.mentions.query, 10, twisterRpc('getmentions', [twister.mentions.query, postsPerRefresh,
{max_id: twister.mentions.lastTorrentId - twister.mentions.lengthFromTorrent}], {max_id: twister.mentions.lastTorrentId - twister.mentions.lengthFromTorrent}],
function (req, res) { function (req, res) {
twister.mentions.scrollQueryActive = false; twister.res[req].scrollQueryActive = false;
twister.res[req].boardAutoAppend = true; // FIXME all pending twists will be appended twister.res[req].boardAutoAppend = true; // FIXME all pending twists will be appended
queryProcess(req, res); queryProcess(req, res);
twister.res[req].boardAutoAppend = false; twister.res[req].boardAutoAppend = false;
@ -174,119 +177,274 @@ function handleMentionsModalScroll(event) {
// --- direct messages --- // --- direct messages ---
var _lastDMIdPerUser = {};
var _newDMsPerUser = {};
function saveDMsToStorage() { function saveDMsToStorage() {
var ns = $.initNamespaceStorage(defaultScreenName); var pool = {};
ns.localStorage.set('lastDMIdPerUser', _lastDMIdPerUser);
ns.localStorage.set('newDMsPerUser', _newDMsPerUser); for (var peerAlias in twister.DMs) {
var twists = [], length = 0;
for (var j in twister.DMs[peerAlias].twists.cached) {
for (var i = 0; i < length; i++)
if (twister.DMs[peerAlias].twists.cached[j].id > twists[i].id) {
twists.splice(i, 0, twister.DMs[peerAlias].twists.cached[j]);
break;
}
if (length === twists.length)
twists.push(twister.DMs[peerAlias].twists.cached[j]);
length++;
}
pool[peerAlias] = {
twists: twists.slice(0, 100), // TODO add an option to specify number of DMs to cache
lastId: twister.DMs[peerAlias].lastId,
};
}
$.initNamespaceStorage(defaultScreenName).localStorage.set('DMs', pool);
} }
function loadDMsFromStorage() { function loadDMsFromStorage() {
var ns = $.initNamespaceStorage(defaultScreenName); var storage = $.initNamespaceStorage(defaultScreenName).localStorage;
if (ns.localStorage.isSet('lastDMIdPerUser'))
_lastDMIdPerUser = ns.localStorage.get('lastDMIdPerUser'); if (storage.isSet('DMs')) {
if (ns.localStorage.isSet('newDMsPerUser')) var pool = storage.get('DMs');
_newDMsPerUser = ns.localStorage.get('newDMsPerUser'); if (typeof pool === 'object') {
for (var peerAlias in pool) {
if (!twister.DMs[peerAlias])
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
for (var i = 0; i < pool[peerAlias].twists.length; i++) {
var j = pool[peerAlias].twists[i].from + '/' + pool[peerAlias].twists[i].time;
if (typeof twister.DMs[peerAlias].twists.cached[j] === 'undefined') {
twister.DMs[peerAlias].twists.cached[j] = pool[peerAlias].twists[i];
twister.DMs[peerAlias].lengthCached++;
if (twister.DMs[peerAlias].twists.cached[j].isNew)
twister.DMs[peerAlias].lengthNew++;
}
}
twister.DMs[peerAlias].lastId = pool[peerAlias].lastId;
}
}
}
// WARN all following storage keys are deprecated (see commit FIXME)
if (storage.isSet('lastDMIdPerUser')) {
var pool = storage.get('lastDMIdPerUser');
if (typeof pool === 'object')
for (var peerAlias in pool) {
if (!twister.DMs[peerAlias])
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
twister.DMs[peerAlias].lastId = pool[peerAlias];
}
storage.remove('lastDMIdPerUser');
}
if (storage.isSet('newDMsPerUser')) {
var pool = storage.get('newDMsPerUser');
if (typeof pool === 'object')
for (var peerAlias in pool) {
if (!twister.DMs[peerAlias])
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
twister.DMs[peerAlias].lengthNew = pool[peerAlias];
}
storage.remove('newDMsPerUser');
}
}
function queryPendingPushDMs(res) {
var lengthNew = 0;
var lengthPending = 0;
for (var peerAlias in res) {
if (!res[peerAlias] || !res[peerAlias].length || !twister.DMs[peerAlias])
continue;
for (var i = 0; i < res[peerAlias].length; i++) {
var j = res[peerAlias][i].from + '/' + res[peerAlias][i].time;
if (typeof twister.DMs[peerAlias].twists.cached[j] === 'undefined') {
twister.DMs[peerAlias].twists.cached[j] = res[peerAlias][i];
twister.DMs[peerAlias].lengthCached++;
twister.DMs[peerAlias].twists.pending.push(j);
lengthPending++;
if (twister.DMs[peerAlias].lastId < res[peerAlias][i].id) {
twister.DMs[peerAlias].lastId = res[peerAlias][i].id;
if ((!twister.DMs[peerAlias].board || !twister.DMs[peerAlias].board.is('html *'))
&& !res[peerAlias][i].fromMe && res[peerAlias][i].from !== defaultScreenName) {
lengthNew++;
twister.DMs[peerAlias].lengthNew += 1;
twister.DMs[peerAlias].twists.cached[j].isNew = true;
}
}
}
}
}
if (lengthPending)
saveDMsToStorage();
return lengthNew;
} }
function requestDMsCount() { function requestDMsCount() {
var followList = []; var list = [];
for (var i = 0; i < followingUsers.length; i++) for (var i = 0; i < followingUsers.length; i++)
followList.push({username: followingUsers[i]}); list.push({username: followingUsers[i]});
for (var i = 0; i < groupChatAliases.length; i++ ) for (var i = 0; i < groupChatAliases.length; i++)
followList.push({username: groupChatAliases[i]}); list.push({username: groupChatAliases[i]});
twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList], twisterRpc('getdirectmsgs', [defaultScreenName, 1, list],
function(req, dmUsers) { function (req, res) {
var newDMsUpdated; var lengthNew = 0, lengthNewMax = 0;
var list = [];
for (var u in dmUsers) { for (var peerAlias in res) {
if (!dmUsers[u]) if (!res[peerAlias] || !res[peerAlias].length)
continue; continue;
var dmData = dmUsers[u][0]; if (!twister.DMs[peerAlias])
if (dmData.from !== defaultScreenName) { twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
if (u in _lastDMIdPerUser && u in _newDMsPerUser) { {boardAutoAppend: true, lastId: 0, lengthNew: 0});
if (dmData.id !== _lastDMIdPerUser[u]) {
_newDMsPerUser[u] += dmData.id - _lastDMIdPerUser[u]; if (res[peerAlias][0].id > twister.DMs[peerAlias].lastId) {
newDMsUpdated = true; lengthNew = res[peerAlias][0].id - twister.DMs[peerAlias].lastId;
} if (lengthNewMax < lengthNew)
} else { lengthNewMax = lengthNew;
_newDMsPerUser[u] = dmData.id + 1;
newDMsUpdated = true; list.push({username: peerAlias});
} } else if (!twister.DMs[peerAlias].lengthCached)
} queryPendingPushDMs(res);
_lastDMIdPerUser[u] = dmData.id;
} }
if (newDMsUpdated) {
saveDMsToStorage(); if (list.length === 1)
var newDMs = getNewDMsCount(); queryProcess(list[0].username + '@direct', res);
if (newDMs) { else if (lengthNewMax === 1) {
$.MAL.updateNewDMsUI(newDMs); if (queryPendingPushDMs(res))
$.MAL.soundNotifyDM(); DMsSummaryProcessNew();
} else if (lengthNewMax) {
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') { twisterRpc('getdirectmsgs', [defaultScreenName, lengthNewMax, list],
$.MAL.showDesktopNotification({ function (req, res) {
body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.', if (typeof res !== 'object' || $.isEmptyObject(res))
tag: 'twister_notification_new_DMs', return;
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: function () {$.MAL.showDMchat();} if (queryPendingPushDMs(res))
}); DMsSummaryProcessNew();
} }, undefined,
} function (req, res) {
var newDMs = getNewGroupDMsCount(); console.warn(polyglot.t('ajax_error',
if (newDMs) { {error: (res && res.message) ? res.message : res}));
$.MAL.updateNewGroupDMsUI(newDMs);
$.MAL.soundNotifyDM();
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') {
$.MAL.showDesktopNotification({
body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newDMs) + '.',
tag: 'twister_notification_new_DMs',
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: function () {$.MAL.showDMchat({group: true});}
});
} }
} );
} }
}, null, }, undefined,
function(req, ret) {console.warn('ajax error:' + ret);}, null function (req, res) {
console.warn(polyglot.t('ajax_error', {error: (res && res.message) ? res.message : res}));
}
); );
} }
function DMsSummaryProcessNew() {
var lengthNew = getNewDMsCount();
if (lengthNew) {
$.MAL.updateNewDMsUI(lengthNew);
$.MAL.soundNotifyDM();
if (!$.mobile) {
if ($.Options.showDesktopNotifDMs.val === 'enable') {
$.MAL.showDesktopNotification({
body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', lengthNew) + '.',
tag: 'twister_notification_new_DMs',
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: function () {$.MAL.showDMchat();}
});
}
var elem = getElem('.directMessages .direct-messages-list');
if (isModalWithElemExists(elem))
modalDMsSummaryDraw(elem);
} else if ($.mobile.activePage.attr('id') !== 'directmsg')
modalDMsSummaryDraw($('#directmsg .direct-messages-list'));
}
lengthNew = getNewGroupDMsCount();
if (lengthNew) {
$.MAL.updateNewGroupDMsUI(lengthNew);
$.MAL.soundNotifyDM();
if (!$.mobile) {
if ($.Options.showDesktopNotifDMs.val === 'enable') {
$.MAL.showDesktopNotification({
body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', lengthNew) + '.',
tag: 'twister_notification_new_DMs',
timeout: $.Options.showDesktopNotifDMsTimer.val,
funcClick: function () {$.MAL.showDMchat({group: true});}
});
}
var elem = getElem('.groupMessages .direct-messages-list');
if (isModalWithElemExists(elem))
modalDMsSummaryDraw(elem, true);
} else if ($.mobile.activePage.attr('id') !== 'directmsg')
modalDMsSummaryDraw($('#directmsg .direct-messages-list'), true);
}
}
function getNewDMsCount() { function getNewDMsCount() {
var newDMs = 0; var lengthNew = 0;
for (var user in _newDMsPerUser) { for (var peerAlias in twister.DMs)
if (user[0] !== '*' && _newDMsPerUser[user]) if (peerAlias[0] !== '*' && twister.DMs[peerAlias].lengthNew)
newDMs += _newDMsPerUser[user]; lengthNew += twister.DMs[peerAlias].lengthNew;
}
return newDMs; return lengthNew;
} }
function getNewGroupDMsCount() { function getNewGroupDMsCount() {
var newDMs = 0; var lengthNew = 0;
for (var user in _newDMsPerUser) { for (var peerAlias in twister.DMs)
if (user[0] === '*' && _newDMsPerUser[user]) if (peerAlias[0] === '*' && twister.DMs[peerAlias].lengthNew)
newDMs += _newDMsPerUser[user]; lengthNew += twister.DMs[peerAlias].lengthNew;
}
return newDMs; return lengthNew;
} }
function resetNewDMsCountForUser(user, lastId) { function resetNewDMsCount() {
_newDMsPerUser[user] = 0; for (var peerAlias in twister.DMs)
_lastDMIdPerUser[user] = lastId; if (peerAlias[0] !== '*') {
twister.DMs[peerAlias].lengthNew = 0;
for (var j in twister.DMs[peerAlias].twists.cached)
delete twister.DMs[peerAlias].twists.cached[j].isNew;
}
saveDMsToStorage(); saveDMsToStorage();
$.MAL.updateNewDMsUI(getNewDMsCount()); $.MAL.updateNewDMsUI(getNewDMsCount());
}
function resetNewDMsCountGroup() {
for (var peerAlias in twister.DMs)
if (peerAlias[0] === '*') {
twister.DMs[peerAlias].lengthNew = 0;
for (var j in twister.DMs[peerAlias].twists.cached)
delete twister.DMs[peerAlias].twists.cached[j].isNew;
}
saveDMsToStorage();
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount()); $.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
} }
function resetNewDMsCountForPeer(peerAlias) {
twister.DMs[peerAlias].lengthNew = 0;
for (var j in twister.DMs[peerAlias].twists.cached)
delete twister.DMs[peerAlias].twists.cached[j].isNew;
saveDMsToStorage();
if (peerAlias[0] !== '*')
$.MAL.updateNewDMsUI(getNewDMsCount());
else
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
}
function updateGroupList() { function updateGroupList() {
twisterRpc('listgroups', [], twisterRpc('listgroups', [],
function(req, ret) {groupChatAliases = ret;}, null, function(req, ret) {groupChatAliases = ret;}, null,
@ -295,6 +453,7 @@ function updateGroupList() {
} }
function initDMsCount() { function initDMsCount() {
twister.DMs = {};
loadDMsFromStorage(); loadDMsFromStorage();
$.MAL.updateNewDMsUI(getNewDMsCount()); $.MAL.updateNewDMsUI(getNewDMsCount());
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount()); $.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
@ -310,3 +469,38 @@ function initDMsCount() {
function newmsgsChangedUser() { function newmsgsChangedUser() {
clearInterval(twister.mentions.interval); clearInterval(twister.mentions.interval);
} }
function handleDMsModalScroll(event) {
if (!event || !event.data.req || !twister.DMs[event.data.req]
|| twister.DMs[event.data.req].scrollQueryActive)
return;
var length = twister.DMs[event.data.req].lastId - twister.DMs[event.data.req].lengthCached + 1;
if (!length)
return;
var elem = $(event.target);
if (elem.scrollTop() < 100) {
twister.DMs[event.data.req].scrollQueryActive = true;
twisterRpc('getdirectmsgs', [defaultScreenName, Math.min(length, postsPerRefresh),
[{username: twister.DMs[event.data.req].query, max_id: length - 1}]],
function (req, res) {
twister.res[req.k].scrollQueryActive = false;
//twister.res[req.k].boardAutoAppend = true; // FIXME all pending twists will be appended
queryProcess(req.k, res);
//twister.res[req.k].boardAutoAppend = false;
if (req.container[0].scrollHeight !== req.containerScrollHeightPrev)
req.container.scrollTop(req.container[0].scrollHeight - req.containerScrollHeightPrev);
}, {
k: twister.DMs[event.data.req].query + '@' + twister.DMs[event.data.req].resource,
container: elem,
containerScrollHeightPrev: elem[0].scrollHeight
},
function (req, res) {
console.warn(polyglot.t('ajax_error',
{error: (res && res.message) ? res.message : res}));
}
);
}
}

17
js/twister_timeline.js

@ -183,13 +183,18 @@ function processReceivedPosts(req, posts)
} }
function updateTimeline(req, posts) { function updateTimeline(req, posts) {
attachPostsToStream($.MAL.getStreamPostsParent(), posts, req.getspam); attachPostsToStream($.MAL.getStreamPostsParent(), posts, true,
function (twist, promoted) {
return {item: postToElem(twist, 'original', promoted), time: twist.userpost.time};
},
req.getspam
);
for (var i = 0; i < posts.length; i++) { for (var i = 0; i < posts.length; i++) {
req.reportProcessedPost(posts[i]['userpost']['n'], posts[i]['userpost']['k'], true); req.reportProcessedPost(posts[i]['userpost']['n'], posts[i]['userpost']['k'], true);
} }
} }
function attachPostsToStream(stream, posts, isPromoted) { function attachPostsToStream(stream, posts, descendingOrder, createElem, createElemReq) {
//console.log('attachPostsToStream:'); //console.log('attachPostsToStream:');
//console.log(posts); //console.log(posts);
@ -204,7 +209,7 @@ function attachPostsToStream(stream, posts, isPromoted) {
for (var i = 0; i < posts.length; i++) { for (var i = 0; i < posts.length; i++) {
//console.log(posts[i]); //console.log(posts[i]);
var isAttached = false; var isAttached = false;
var intrantPost = {item: postToElem(posts[i], 'original', isPromoted), time: posts[i].userpost.time}; var intrantPost = createElem(posts[i], createElemReq);
intrantPost.item.attr('data-time', intrantPost.time); intrantPost.item.attr('data-time', intrantPost.time);
if (streamPosts.length) { if (streamPosts.length) {
@ -213,10 +218,10 @@ function attachPostsToStream(stream, posts, isPromoted) {
if (intrantPost.time === streamPosts[j].time && if (intrantPost.time === streamPosts[j].time &&
intrantPost.item[0].innerHTML === streamPosts[j].item[0].innerHTML) { intrantPost.item[0].innerHTML === streamPosts[j].item[0].innerHTML) {
isAttached = true; isAttached = true;
console.log('appending of duplicate twist prevented'); console.warn('appending of duplicate twist prevented');
break; break;
} else if (intrantPost.time > streamPosts[j].time) { } else if (descendingOrder ?
// this post in stream is older, so post must be inserted above intrantPost.time > streamPosts[j].time : intrantPost.time < streamPosts[j].time) {
intrantPost.item.insertBefore(streamPosts[j].item).show(); intrantPost.item.insertBefore(streamPosts[j].item).show();
streamPosts.splice(j, 0, intrantPost); streamPosts.splice(j, 0, intrantPost);
isAttached = true; isAttached = true;

Loading…
Cancel
Save