|
|
@ -6,130 +6,91 @@ |
|
|
|
|
|
|
|
|
|
|
|
// --- mentions ---
|
|
|
|
// --- mentions ---
|
|
|
|
|
|
|
|
|
|
|
|
var _knownMentions = {} |
|
|
|
|
|
|
|
var _lastMentionTime = 0; |
|
|
|
|
|
|
|
var _newMentions = 0; |
|
|
|
|
|
|
|
var _lastLocalMentionId = -1; |
|
|
|
|
|
|
|
var PURGE_OLD_MENTIONS_TIMEOUT = 3600 * 24 * 30; // one month
|
|
|
|
|
|
|
|
var _newMentionsUpdated = false; |
|
|
|
|
|
|
|
var _newDMsUpdated = false; |
|
|
|
var _newDMsUpdated = false; |
|
|
|
var groupChatAliases = [] |
|
|
|
var groupChatAliases = [] |
|
|
|
|
|
|
|
|
|
|
|
// process a mention received to check if it is really new
|
|
|
|
function saveMentionsToStorage() { |
|
|
|
function processMention(user, mentionTime, data) { |
|
|
|
var twists = [], length = 0; |
|
|
|
var key = user + ';' + mentionTime; |
|
|
|
for (var j in twister.mentions.twists.cached) { |
|
|
|
var curTime = new Date().getTime() / 1000; |
|
|
|
for (var i = 0; i < length; i++) |
|
|
|
if (mentionTime > curTime + 7200) // 3600 * 2
|
|
|
|
if (twister.mentions.twists.cached[j].userpost.time > twists[i].userpost.time) { |
|
|
|
console.warn('ignoring mention from the future'); |
|
|
|
twists.splice(i, 0, twister.mentions.twists.cached[j]); |
|
|
|
else { |
|
|
|
break; |
|
|
|
if (!_knownMentions[key]) { |
|
|
|
|
|
|
|
// mention must be somewhat recent compared to last known one to be considered new
|
|
|
|
|
|
|
|
if (mentionTime + 259200 > _lastMentionTime) { // 3600 * 24 * 3
|
|
|
|
|
|
|
|
_newMentions++; |
|
|
|
|
|
|
|
_newMentionsUpdated = true; |
|
|
|
|
|
|
|
_lastMentionTime = Math.max(mentionTime, _lastMentionTime); |
|
|
|
|
|
|
|
data.isNew = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var req = defaultScreenName + '@mention'; |
|
|
|
|
|
|
|
var j = data.userpost.n + '/' + data.userpost.time; |
|
|
|
|
|
|
|
if (typeof twister.res[req].twists.cached[j] === 'undefined') { |
|
|
|
|
|
|
|
twister.res[req].twists.cached[j] = data; |
|
|
|
|
|
|
|
twister.res[req].twists.pending.push(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
_knownMentions[key] = {mentionTime: mentionTime, data: data}; |
|
|
|
|
|
|
|
purgeOldMentions(); |
|
|
|
|
|
|
|
saveMentionsToStorage(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (length === twists.length) |
|
|
|
|
|
|
|
twists.push(twister.mentions.twists.cached[j]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
length++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$.initNamespaceStorage(defaultScreenName).localStorage |
|
|
|
|
|
|
|
.set('mentions', { |
|
|
|
|
|
|
|
twists: twists.slice(0, 100), // TODO add an option to specify number of mentions to cache
|
|
|
|
|
|
|
|
lastTime: twister.mentions.lastTime, |
|
|
|
|
|
|
|
lastTorrentId: twister.mentions.lastTorrentId |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function purgeOldMentions() { |
|
|
|
function loadMentionsFromStorage() { |
|
|
|
for (var key in _knownMentions) { |
|
|
|
var storage = $.initNamespaceStorage(defaultScreenName).localStorage; |
|
|
|
if (_knownMentions[key]) { |
|
|
|
|
|
|
|
if (!_knownMentions[key].mentionTime || !_knownMentions[key].data || |
|
|
|
if (storage.isSet('mentions')) { |
|
|
|
_knownMentions[key].mentionTime + PURGE_OLD_MENTIONS_TIMEOUT < _lastMentionTime) { |
|
|
|
var mentions = storage.get('mentions'); |
|
|
|
delete _knownMentions[key]; |
|
|
|
if (typeof mentions === 'object') { |
|
|
|
|
|
|
|
for (var i = 0; i < mentions.twists.length; i++) { |
|
|
|
|
|
|
|
var j = mentions.twists[i].userpost.n + '/' + mentions.twists[i].userpost.time; |
|
|
|
|
|
|
|
if (typeof twister.mentions.twists.cached[j] === 'undefined') { |
|
|
|
|
|
|
|
twister.mentions.twists.cached[j] = mentions.twists[i]; |
|
|
|
|
|
|
|
if (twister.mentions.twists.cached[j].isNew) |
|
|
|
|
|
|
|
twister.mentions.lengthNew++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
twister.mentions.lastTime = mentions.lastTime; |
|
|
|
|
|
|
|
twister.mentions.lastTorrentId = mentions.lastTorrentId; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function saveMentionsToStorage() { |
|
|
|
// WARN all following storage keys are deprecated
|
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName); |
|
|
|
if (storage.isSet('knownMentions')) { |
|
|
|
ns.localStorage.set('knownMentions', _knownMentions); |
|
|
|
var mentions = storage.get('knownMentions'); |
|
|
|
ns.localStorage.set('lastMentionTime', _lastMentionTime); |
|
|
|
if (typeof mentions === 'object') |
|
|
|
ns.localStorage.set('newMentions', _newMentions); |
|
|
|
for (var i in mentions) { |
|
|
|
ns.localStorage.set('lastLocalMentionId', _lastLocalMentionId); |
|
|
|
var j = mentions[i].data.userpost.n + '/' + mentions[i].mentionTime; |
|
|
|
} |
|
|
|
if (typeof twister.mentions.twists.cached[j] === 'undefined') { |
|
|
|
|
|
|
|
twister.mentions.twists.cached[j] = mentions[i].data; |
|
|
|
|
|
|
|
if (twister.mentions.twists.cached[j].isNew) |
|
|
|
|
|
|
|
twister.mentions.lengthNew++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function loadMentionsFromStorage() { |
|
|
|
storage.remove('knownMentions'); |
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName); |
|
|
|
} |
|
|
|
if (ns.localStorage.isSet('knownMentions')) |
|
|
|
if (storage.isSet('lastMentionTime')) { |
|
|
|
_knownMentions = ns.localStorage.get('knownMentions'); |
|
|
|
twister.mentions.lastTime = storage.get('lastMentionTime'); |
|
|
|
if (ns.localStorage.isSet('lastMentionTime')) |
|
|
|
storage.remove('lastMentionTime'); |
|
|
|
_lastMentionTime = ns.localStorage.get('lastMentionTime'); |
|
|
|
} |
|
|
|
if (ns.localStorage.isSet('newMentions')) |
|
|
|
if (storage.isSet('lastLocalMentionId')) { |
|
|
|
_newMentions = ns.localStorage.get('newMentions'); |
|
|
|
twister.mentions.lastTorrentId = storage.get('lastLocalMentionId'); |
|
|
|
if (ns.localStorage.isSet('lastLocalMentionId')) |
|
|
|
storage.remove('lastLocalMentionId'); |
|
|
|
_lastLocalMentionId = ns.localStorage.get('lastLocalMentionId'); |
|
|
|
} |
|
|
|
|
|
|
|
if (storage.isSet('newMentions')) |
|
|
|
|
|
|
|
storage.remove('newMentions'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function requestMentionsCount() { |
|
|
|
function requestMentionsCount() { |
|
|
|
// first: getmentions from torrents we follow
|
|
|
|
// first: getmentions from torrents we follow
|
|
|
|
twisterRpc('getmentions', [defaultScreenName, 100, {since_id: _lastLocalMentionId}], |
|
|
|
twisterRpc('getmentions', [defaultScreenName, 100, {since_id: twister.mentions.lastTorrentId}], |
|
|
|
function(args, data) { |
|
|
|
processNewMentions, undefined, |
|
|
|
if (data) { |
|
|
|
|
|
|
|
for (var i = 0; i < data.length; i++) { |
|
|
|
|
|
|
|
_lastLocalMentionId = Math.max(_lastLocalMentionId, data[i].id); |
|
|
|
|
|
|
|
var userpost = data[i].userpost; |
|
|
|
|
|
|
|
processMention(userpost.n, userpost.time, data[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$.MAL.updateNewMentionsUI(_newMentions); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, null, |
|
|
|
|
|
|
|
function(req, ret) {console.warn('getmentions API requires twister-core > 0.9.27');}, null |
|
|
|
function(req, ret) {console.warn('getmentions API requires twister-core > 0.9.27');}, null |
|
|
|
); |
|
|
|
); |
|
|
|
// second: get mentions from dht (not-following)
|
|
|
|
// second: get mentions from dht (not-following)
|
|
|
|
dhtget(defaultScreenName, 'mention', 'm', |
|
|
|
dhtget(defaultScreenName, 'mention', 'm', |
|
|
|
function(args, data) { |
|
|
|
processNewMentions, undefined, |
|
|
|
if (data) { |
|
|
|
twister.res[defaultScreenName + '@mention'].timeoutArgs |
|
|
|
for (var i = 0; i < data.length; i++) { |
|
|
|
|
|
|
|
var userpost = data[i].userpost; |
|
|
|
|
|
|
|
processMention(userpost.n, userpost.time, data[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$.MAL.updateNewMentionsUI(_newMentions); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, {}, |
|
|
|
|
|
|
|
[10000, 2000, 3] // use extended timeout parameters (requires twister_core >= 0.9.14)
|
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (_newMentionsUpdated) { |
|
|
|
|
|
|
|
_newMentionsUpdated = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_newMentions) { |
|
|
|
|
|
|
|
$.MAL.soundNotifyMentions(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifMentions.val === 'enable') |
|
|
|
|
|
|
|
$.MAL.showDesktopNotification({ |
|
|
|
|
|
|
|
body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', _newMentions) + '.', |
|
|
|
|
|
|
|
tag: 'twister_notification_new_mentions', |
|
|
|
|
|
|
|
timeout: $.Options.showDesktopNotifMentionsTimer.val, |
|
|
|
|
|
|
|
funcClick: function () { |
|
|
|
|
|
|
|
var req = defaultScreenName + '@mention'; |
|
|
|
|
|
|
|
if (!focusModalWithElement(twister.res[req].board, |
|
|
|
|
|
|
|
function (req) { |
|
|
|
|
|
|
|
twister.res[req].board.closest('.postboard') |
|
|
|
|
|
|
|
.find('.postboard-news').click(); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
req |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
$.MAL.showMentions(defaultScreenName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// was moved here from requestDMsCount() because that is not ticking right
|
|
|
|
// was moved here from requestDMsCount() because that is not ticking right
|
|
|
|
// we would place it with other notifications into separate notification center
|
|
|
|
// we would place it with other notifications into separate notification center
|
|
|
|
if (_newDMsUpdated) { |
|
|
|
if (_newDMsUpdated) { |
|
|
@ -164,14 +125,92 @@ function requestMentionsCount() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function resetMentionsCount() { |
|
|
|
function processNewMentions(req, res) { |
|
|
|
_newMentions = 0; |
|
|
|
if (!res || !res.length) |
|
|
|
for (var key in _knownMentions) { |
|
|
|
return; |
|
|
|
if (_knownMentions[key] && _knownMentions[key].data) |
|
|
|
|
|
|
|
delete _knownMentions[key].data.isNew |
|
|
|
var lengthNew = 0; |
|
|
|
|
|
|
|
var lengthPending = twister.mentions.twists.pending.length; |
|
|
|
|
|
|
|
var timeCurrent = new Date().getTime() / 1000 + 7200; // 60 * 60 * 2
|
|
|
|
|
|
|
|
var timeLastMention = twister.mentions.lastTime; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < res.length; i++) { |
|
|
|
|
|
|
|
if (res[i].userpost.time > timeCurrent) { |
|
|
|
|
|
|
|
console.warn('ignoring mention from the future:'); |
|
|
|
|
|
|
|
console.log(res[i]); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (res[i].id) { |
|
|
|
|
|
|
|
twister.mentions.lastTorrentId = Math.max(twister.mentions.lastTorrentId, res[i].id); |
|
|
|
|
|
|
|
delete res[i].id; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var j = res[i].userpost.n + '/' + res[i].userpost.time; |
|
|
|
|
|
|
|
if (typeof twister.mentions.twists.cached[j] === 'undefined') { |
|
|
|
|
|
|
|
twister.mentions.twists.cached[j] = res[i]; |
|
|
|
|
|
|
|
twister.mentions.twists.pending.push(j); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// mention must be somewhat recent compared to last known one to be considered new
|
|
|
|
|
|
|
|
if (res[i].userpost.time + 259200 > timeLastMention) { // 3600 * 24 * 3
|
|
|
|
|
|
|
|
lengthNew++; |
|
|
|
|
|
|
|
twister.mentions.lastTime = Math.max(res[i].userpost.time, twister.mentions.lastTime); |
|
|
|
|
|
|
|
twister.mentions.twists.cached[j].isNew = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (lengthNew) { |
|
|
|
|
|
|
|
twister.mentions.lengthNew += lengthNew; |
|
|
|
|
|
|
|
$.MAL.updateNewMentionsUI(twister.mentions.lengthNew); |
|
|
|
|
|
|
|
$.MAL.soundNotifyMentions(); |
|
|
|
|
|
|
|
if (!$.mobile && $.Options.showDesktopNotifMentions.val === 'enable') |
|
|
|
|
|
|
|
$.MAL.showDesktopNotification({ |
|
|
|
|
|
|
|
body: polyglot.t('You got') + ' ' + polyglot.t('new_mentions', twister.mentions.lengthNew) + '.', |
|
|
|
|
|
|
|
tag: 'twister_notification_new_mentions', |
|
|
|
|
|
|
|
timeout: $.Options.showDesktopNotifMentionsTimer.val, |
|
|
|
|
|
|
|
funcClick: function () { |
|
|
|
|
|
|
|
var req = defaultScreenName + '@mention'; |
|
|
|
|
|
|
|
if (!twister.res[req].board || !focusModalWithElement(twister.res[req].board, |
|
|
|
|
|
|
|
function (req) { |
|
|
|
|
|
|
|
twister.res[req].board.closest('.postboard') |
|
|
|
|
|
|
|
.find('.postboard-news').click(); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
req |
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
$.MAL.showMentions(defaultScreenName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (twister.mentions.twists.pending.length > lengthPending) { |
|
|
|
|
|
|
|
saveMentionsToStorage(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var req = defaultScreenName + '@mention'; |
|
|
|
|
|
|
|
if (!twister.res[req].board || !isModalWithElemExists(twister.res[req].board)) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!twister.res[req].board.children().length || twister.res[req].boardAutoAppend) |
|
|
|
|
|
|
|
queryPendingDraw(req); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
twister.res[req].board.closest('div').find('.postboard-news') // FIXME we'd replace 'div' with '.postboard' but need to dig through tmobile first
|
|
|
|
|
|
|
|
.text(polyglot.t('new_posts', twister.mentions.twists.pending.length)) |
|
|
|
|
|
|
|
.fadeIn('slow') |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
twister.res[req].board.closest('div').find('.postboard-loading').hide(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function resetMentionsCount() { |
|
|
|
|
|
|
|
twister.mentions.lengthNew = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var j in twister.mentions.twists.cached) |
|
|
|
|
|
|
|
if (twister.mentions.twists.cached[j].isNew) |
|
|
|
|
|
|
|
delete twister.mentions.twists.cached[j].isNew; |
|
|
|
|
|
|
|
|
|
|
|
saveMentionsToStorage(); |
|
|
|
saveMentionsToStorage(); |
|
|
|
$.MAL.updateNewMentionsUI(_newMentions); |
|
|
|
$.MAL.updateNewMentionsUI(twister.mentions.lengthNew); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function initMentionsCount() { |
|
|
|
function initMentionsCount() { |
|
|
@ -179,27 +218,21 @@ function initMentionsCount() { |
|
|
|
twister.res[req] = { |
|
|
|
twister.res[req] = { |
|
|
|
query: defaultScreenName, |
|
|
|
query: defaultScreenName, |
|
|
|
resource: 'mention', |
|
|
|
resource: 'mention', |
|
|
|
|
|
|
|
timeoutArgs: [10000, 2000, 3], |
|
|
|
twists: { |
|
|
|
twists: { |
|
|
|
cached: {}, |
|
|
|
cached: {}, |
|
|
|
pending: [] |
|
|
|
pending: [], |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
lastTime: 0, |
|
|
|
|
|
|
|
lastTorrentId: -1, |
|
|
|
|
|
|
|
lengthNew: 0 |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
twister.mentions = twister.res[req]; |
|
|
|
loadMentionsFromStorage(); |
|
|
|
loadMentionsFromStorage(); |
|
|
|
queryPendingPush(req, getMentionsData()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$.MAL.updateNewMentionsUI(_newMentions); |
|
|
|
$.MAL.updateNewMentionsUI(twister.mentions.lengthNew); |
|
|
|
requestMentionsCount(); |
|
|
|
requestMentionsCount(); |
|
|
|
setInterval(requestMentionsCount, 10000); |
|
|
|
twister.mentions.interval = setInterval(requestMentionsCount, 10000); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getMentionsData() { |
|
|
|
|
|
|
|
mentions = [] |
|
|
|
|
|
|
|
for (var key in _knownMentions) { |
|
|
|
|
|
|
|
if (_knownMentions[key] && _knownMentions[key].data) { |
|
|
|
|
|
|
|
mentions.push(_knownMentions[key].data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return mentions; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// --- direct messages ---
|
|
|
|
// --- direct messages ---
|
|
|
@ -307,7 +340,5 @@ function initDMsCount() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function newmsgsChangedUser() { |
|
|
|
function newmsgsChangedUser() { |
|
|
|
_knownMentions = {} |
|
|
|
clearInterval(twister.mentions.interval); |
|
|
|
_lastMentionTime = 0; |
|
|
|
|
|
|
|
_newMentions = 0; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|