|
|
|
// twister_newmsgs.js
|
|
|
|
// 2013 Miguel Freitas
|
|
|
|
//
|
|
|
|
// Periodically check for new mentions and private messages (DMs)
|
|
|
|
// Update UI counters in top bar. Load/save state to localStorage.
|
|
|
|
|
|
|
|
// --- 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 groupChatAliases = []
|
|
|
|
|
|
|
|
// process a mention received to check if it is really new
|
|
|
|
function processMention(user, mentionTime, data) {
|
|
|
|
var key = user + ';' + mentionTime;
|
|
|
|
var curTime = new Date().getTime() / 1000;
|
|
|
|
if (mentionTime > curTime + 7200) // 3600 * 2
|
|
|
|
console.warn('ignoring mention from the future');
|
|
|
|
else {
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function purgeOldMentions() {
|
|
|
|
for (var key in _knownMentions) {
|
|
|
|
if (_knownMentions[key]) {
|
|
|
|
if (!_knownMentions[key].mentionTime || !_knownMentions[key].data ||
|
|
|
|
_knownMentions[key].mentionTime + PURGE_OLD_MENTIONS_TIMEOUT < _lastMentionTime) {
|
|
|
|
delete _knownMentions[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveMentionsToStorage() {
|
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName);
|
|
|
|
ns.localStorage.set('knownMentions', _knownMentions);
|
|
|
|
ns.localStorage.set('lastMentionTime', _lastMentionTime);
|
|
|
|
ns.localStorage.set('newMentions', _newMentions);
|
|
|
|
ns.localStorage.set('lastLocalMentionId', _lastLocalMentionId);
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadMentionsFromStorage() {
|
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName);
|
|
|
|
if (ns.localStorage.isSet('knownMentions'))
|
|
|
|
_knownMentions = ns.localStorage.get('knownMentions');
|
|
|
|
if (ns.localStorage.isSet('lastMentionTime'))
|
|
|
|
_lastMentionTime = ns.localStorage.get('lastMentionTime');
|
|
|
|
if (ns.localStorage.isSet('newMentions'))
|
|
|
|
_newMentions = ns.localStorage.get('newMentions');
|
|
|
|
if (ns.localStorage.isSet('lastLocalMentionId'))
|
|
|
|
_lastLocalMentionId = ns.localStorage.get('lastLocalMentionId');
|
|
|
|
}
|
|
|
|
|
|
|
|
function requestMentionsCount() {
|
|
|
|
// first: getmentions from torrents we follow
|
|
|
|
twisterRpc('getmentions', [defaultScreenName, 100, {since_id: _lastLocalMentionId}],
|
|
|
|
function(args, data) {
|
|
|
|
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
|
|
|
|
);
|
|
|
|
// second: get mentions from dht (not-following)
|
|
|
|
dhtget(defaultScreenName, 'mention', 'm',
|
|
|
|
function(args, data) {
|
|
|
|
if (data) {
|
|
|
|
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
|
|
|
|
// we would place it with other notifications into separate notification center
|
|
|
|
if (_newDMsUpdated) {
|
|
|
|
_newDMsUpdated = false;
|
|
|
|
|
|
|
|
var newDMs = getNewDMsCount();
|
|
|
|
if (newDMs) {
|
|
|
|
$.MAL.soundNotifyDM();
|
|
|
|
|
|
|
|
if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifDMs.val === 'enable') {
|
|
|
|
$.MAL.showDesktopNotification({
|
|
|
|
body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.',
|
|
|
|
tag: 'twister_notification_new_DMs',
|
|
|
|
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
|
|
|
funcClick: function () {$.MAL.showDMchat();}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var newDMs = getNewGroupDMsCount();
|
|
|
|
if (newDMs) {
|
|
|
|
$.MAL.soundNotifyDM();
|
|
|
|
|
|
|
|
if (!$.hasOwnProperty('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});}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function resetMentionsCount() {
|
|
|
|
_newMentions = 0;
|
|
|
|
for (var key in _knownMentions) {
|
|
|
|
if (_knownMentions[key] && _knownMentions[key].data)
|
|
|
|
delete _knownMentions[key].data.isNew
|
|
|
|
}
|
|
|
|
saveMentionsToStorage();
|
|
|
|
$.MAL.updateNewMentionsUI(_newMentions);
|
|
|
|
}
|
|
|
|
|
|
|
|
function initMentionsCount() {
|
|
|
|
var req = defaultScreenName + '@mention';
|
|
|
|
twister.res[req] = {
|
|
|
|
query: defaultScreenName,
|
|
|
|
resource: 'mention',
|
|
|
|
twists: {
|
|
|
|
cached: {},
|
|
|
|
pending: []
|
|
|
|
}
|
|
|
|
};
|
|
|
|
loadMentionsFromStorage();
|
|
|
|
queryPendingPush(req, getMentionsData());
|
|
|
|
|
|
|
|
$.MAL.updateNewMentionsUI(_newMentions);
|
|
|
|
requestMentionsCount();
|
|
|
|
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 ---
|
|
|
|
|
|
|
|
var _lastDMIdPerUser = {};
|
|
|
|
var _newDMsPerUser = {};
|
|
|
|
|
|
|
|
function saveDMsToStorage() {
|
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName);
|
|
|
|
ns.localStorage.set('lastDMIdPerUser', _lastDMIdPerUser);
|
|
|
|
ns.localStorage.set('newDMsPerUser', _newDMsPerUser);
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadDMsFromStorage() {
|
|
|
|
var ns = $.initNamespaceStorage(defaultScreenName);
|
|
|
|
if (ns.localStorage.isSet('lastDMIdPerUser'))
|
|
|
|
_lastDMIdPerUser = ns.localStorage.get('lastDMIdPerUser');
|
|
|
|
if (ns.localStorage.isSet('newDMsPerUser'))
|
|
|
|
_newDMsPerUser = ns.localStorage.get('newDMsPerUser');
|
|
|
|
}
|
|
|
|
|
|
|
|
function requestDMsCount() {
|
|
|
|
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],
|
|
|
|
function(req, dmUsers) {
|
|
|
|
for (var u in dmUsers) {
|
|
|
|
if (dmUsers[u]) {
|
|
|
|
var dmData = dmUsers[u][0];
|
|
|
|
if (u in _lastDMIdPerUser && u in _newDMsPerUser) {
|
|
|
|
if (dmData.id !== _lastDMIdPerUser[u]) {
|
|
|
|
_newDMsPerUser[u] += dmData.id - _lastDMIdPerUser[u];
|
|
|
|
_newDMsUpdated = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_newDMsPerUser[u] = dmData.id + 1;
|
|
|
|
_newDMsUpdated = true;
|
|
|
|
}
|
|
|
|
_lastDMIdPerUser[u] = dmData.id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_newDMsUpdated) {
|
|
|
|
saveDMsToStorage();
|
|
|
|
$.MAL.updateNewDMsUI(getNewDMsCount());
|
|
|
|
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
|
|
|
}
|
|
|
|
}, null,
|
|
|
|
function(req, ret) {console.warn('ajax error:' + ret);}, null
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getNewDMsCount() {
|
|
|
|
var newDMs = 0;
|
|
|
|
|
|
|
|
for (var user in _newDMsPerUser) {
|
|
|
|
if (user[0] !== '*' && _newDMsPerUser[user])
|
|
|
|
newDMs += _newDMsPerUser[user];
|
|
|
|
}
|
|
|
|
|
|
|
|
return newDMs;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getNewGroupDMsCount() {
|
|
|
|
var newDMs = 0;
|
|
|
|
|
|
|
|
for (var user in _newDMsPerUser) {
|
|
|
|
if (user[0] === '*' && _newDMsPerUser[user])
|
|
|
|
newDMs += _newDMsPerUser[user];
|
|
|
|
}
|
|
|
|
|
|
|
|
return newDMs;
|
|
|
|
}
|
|
|
|
|
|
|
|
function resetNewDMsCountForUser(user, lastId) {
|
|
|
|
_newDMsPerUser[user] = 0;
|
|
|
|
_lastDMIdPerUser[user] = lastId;
|
|
|
|
|
|
|
|
saveDMsToStorage();
|
|
|
|
$.MAL.updateNewDMsUI(getNewDMsCount());
|
|
|
|
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateGroupList() {
|
|
|
|
twisterRpc('listgroups', [],
|
|
|
|
function(req, ret) {groupChatAliases = ret;}, null,
|
|
|
|
function(req, ret) {console.warn('twisterd >= 0.9.30 required for listgroups');}, null
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function initDMsCount() {
|
|
|
|
loadDMsFromStorage();
|
|
|
|
$.MAL.updateNewDMsUI(getNewDMsCount());
|
|
|
|
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
|
|
|
//quick hack to obtain list of group chat aliases
|
|
|
|
updateGroupList();
|
|
|
|
setInterval(updateGroupList, 60000);
|
|
|
|
|
|
|
|
setTimeout(requestDMsCount, 200);
|
|
|
|
//polling not needed: processNewPostsConfirmation will call requestDMsCount.
|
|
|
|
//setInterval('requestDMsCount()', 5000);
|
|
|
|
}
|
|
|
|
|
|
|
|
function newmsgsChangedUser() {
|
|
|
|
_knownMentions = {}
|
|
|
|
_lastMentionTime = 0;
|
|
|
|
_newMentions = 0;
|
|
|
|
}
|