@ -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 re s) {
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 le ngthN ew = 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 le ngthN ew;
}
}
function getNewGroupDMsCount ( ) {
function getNewGroupDMsCount ( ) {
var newDMs = 0 ;
var le ngthN ew = 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 le ngthN ew;
}
}
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 } ) ) ;
}
) ;
}
}