revamped handling of unread messages, so that a socket call is made to all socket clients whenever a new unread message is available. Prior behaviour had the unread count updated via ajax call on ajaxify (which was clumsy at best and didn't update automagically)

v1.18.x
Julian Lam 11 years ago
parent 43b012b32e
commit d9ee9bf5e3

@ -183,7 +183,7 @@
if (chat.modalExists(data.fromuid)) {
modal = chat.getModal(data.fromuid);
chat.appendChatMessage(modal, data.message, data.timestamp);
if (modal.is(":visible")) {
chat.load(modal.attr('UUID'));
} else {
@ -196,6 +196,24 @@
});
});
function updateUnreadCount(count) {
var badge = $('#numUnreadBadge');
badge.html(count > 20 ? '20+' : count);
if (count > 0) {
badge
.removeClass('badge-inverse')
.addClass('badge-important');
} else {
badge
.removeClass('badge-important')
.addClass('badge-inverse');
}
}
socket.on('event:unread.updateCount', updateUnreadCount);
socket.emit('api:unread.count', updateUnreadCount);
require(['mobileMenu'], function(mobileMenu) {
mobileMenu.init();
});

@ -185,20 +185,20 @@
}
});
jQuery.getJSON(RELATIVE_PATH + '/api/unread/total', function(data) {
var badge = jQuery('#numUnreadBadge');
badge.html(data.count > 20 ? '20+' : data.count);
if (data.count > 0) {
badge
.removeClass('badge-inverse')
.addClass('badge-important');
} else {
badge
.removeClass('badge-important')
.addClass('badge-inverse');
}
});
// jQuery.getJSON(RELATIVE_PATH + '/api/unread/total', function(data) {
// var badge = jQuery('#numUnreadBadge');
// badge.html(data.count > 20 ? '20+' : data.count);
// if (data.count > 0) {
// badge
// .removeClass('badge-inverse')
// .addClass('badge-important');
// } else {
// badge
// .removeClass('badge-important')
// .addClass('badge-inverse');
// }
// });
},
isRelativeUrl: function(url) {

@ -28,7 +28,7 @@
}
Feed.updateTopic = function (tid, callback) {
topics.getTopicWithPosts(tid, 0, 0, -1, function (err, topicData) {
topics.getTopicWithPosts(tid, 0, 0, -1, true, function (err, topicData) {
if (err) {
return callback(new Error('topic-invalid'));
}

@ -149,6 +149,9 @@ var RDB = require('./redis'),
next();
});
},
function(next) {
topics.pushUnreadCount(null, next);
},
function(next) {
Posts.getCidByPid(postData.pid, function(err, cid) {
if(err) {

@ -115,7 +115,7 @@ var path = require('path'),
app.get('/topic/:id/:slug?', function (req, res, next) {
var uid = (req.user) ? req.user.uid : 0;
topics.getTopicWithPosts(req.params.id, uid, 0, 10, function (err, data) {
topics.getTopicWithPosts(req.params.id, uid, 0, 10, false, function (err, data) {
if (!err) {
if (data.deleted === '1' && data.expose_tools === 0) {
return res.json(404, {});

@ -78,6 +78,11 @@ var DebugRoute = function(app) {
});
});
});
app.get('/test', function(req, res) {
topics.pushUnreadCount();
res.send();
});
});
};

@ -17,7 +17,9 @@ var async = require('async'),
notifications = require('./notifications'),
feed = require('./feed'),
favourites = require('./favourites'),
meta = require('./meta');
meta = require('./meta')
websockets = require('./websockets');
(function(Topics) {
@ -91,7 +93,6 @@ var async = require('async'),
Topics.markAsRead(tid, uid);
});
// in future it may be possible to add topics to several categories, so leaving the door open here.
RDB.zadd('categories:' + cid + ':tid', timestamp, tid);
RDB.hincrby('category:' + cid, 'topic_count', 1);
@ -109,6 +110,8 @@ var async = require('async'),
// Auto-subscribe the post creator to the newly created topic
threadTools.toggleFollow(tid, uid);
Topics.pushUnreadCount();
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
topicData.unreplied = 1;
@ -394,6 +397,29 @@ var async = require('async'),
});
};
Topics.pushUnreadCount = function(uids, callback) {
console.log('uids', uids);
if (uids == 0) throw new Error();
if (!uids) {
clients = websockets.getConnectedClients();
uids = Object.keys(clients);
} else if (!Array.isArray(uids)) {
uids = [uids];
}
async.each(uids, function(uid, next) {
Topics.getUnreadTids(uid, 0, 19, function(err, tids) {
websockets.in('uid_' + uid).emit('event:unread.updateCount', tids.length);
});
}, function(err) {
winston.error(err);
if (callback) {
callback();
}
});
};
Topics.getTopicsByTids = function(tids, current_user, callback, category_id) {
var retrieved_topics = [];
@ -497,14 +523,18 @@ var async = require('async'),
}
Topics.getTopicWithPosts = function(tid, current_user, start, end, callback) {
Topics.getTopicWithPosts = function(tid, current_user, start, end, quiet, callback) {
threadTools.exists(tid, function(exists) {
if (!exists) {
return callback(new Error('Topic tid \'' + tid + '\' not found'));
}
Topics.markAsRead(tid, current_user);
Topics.increaseViewCount(tid);
// "quiet" is used for things like RSS feed updating, HTML parsing for non-js users, etc
if (!quiet) {
Topics.markAsRead(tid, current_user);
Topics.pushUnreadCount(current_user);
Topics.increaseViewCount(tid);
}
function getTopicData(next) {
Topics.getTopicData(tid, next);

@ -465,7 +465,7 @@ var path = require('path'),
async.waterfall([
function (next) {
topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function (err, topicData) {
topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, true, function (err, topicData) {
if (topicData) {
if (topicData.deleted === '1' && topicData.expose_tools === 0) {
return next(new Error('Topic deleted'), null);

@ -66,7 +66,6 @@ websockets.init = function(io) {
var hs = socket.handshake,
sessionID, uid, lastPostTime = 0;
// Validate the session, if present
socketCookieParser(hs, {}, function(err) {
sessionID = socket.handshake.signedCookies["express.sid"];
@ -106,8 +105,6 @@ websockets.init = function(io) {
});
});
socket.on('disconnect', function() {
var index = userSockets[uid].indexOf(socket);
@ -870,6 +867,12 @@ websockets.init = function(io) {
});
});
socket.on('api:unread.count', function(callback) {
topics.getUnreadTids(uid, 0, 19, function(err, tids) {
socket.emit('event:unread.updateCount', tids.length);
});
});
socket.on('api:category.loadMore', function(data, callback) {
var start = data.after,
end = start + 9;
@ -1139,6 +1142,10 @@ websockets.init = function(io) {
websockets.in = function(room) {
return io.sockets.in(room);
};
websockets.getConnectedClients = function() {
return userSockets;
}
}
})(module.exports);

Loading…
Cancel
Save