mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-07 06:25:50 +01:00
merged master
This commit is contained in:
@@ -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) {
|
require(['mobileMenu'], function(mobileMenu) {
|
||||||
mobileMenu.init();
|
mobileMenu.init();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -184,21 +184,6 @@
|
|||||||
notificationIcon.className = 'fa fa-circle active';
|
notificationIcon.className = 'fa fa-circle active';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
isRelativeUrl: function(url) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
Feed.updateTopic = function (tid, callback) {
|
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) {
|
if (err) {
|
||||||
if(callback) {
|
if(callback) {
|
||||||
return callback(new Error('topic-invalid'));
|
return callback(new Error('topic-invalid'));
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ var db = require('./database'),
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
function(next) {
|
||||||
|
topics.pushUnreadCount(null, next);
|
||||||
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
Posts.getCidByPid(postData.pid, function(err, cid) {
|
Posts.getCidByPid(postData.pid, function(err, cid) {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ var path = require('path'),
|
|||||||
|
|
||||||
app.get('/topic/:id/:slug?', function (req, res, next) {
|
app.get('/topic/:id/:slug?', function (req, res, next) {
|
||||||
var uid = (req.user) ? req.user.uid : 0;
|
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 (!err) {
|
||||||
if (parseInt(data.deleted, 10) === 1 && parseInt(data.expose_tools, 10) === 0) {
|
if (parseInt(data.deleted, 10) === 1 && parseInt(data.expose_tools, 10) === 0) {
|
||||||
return res.json(404, {});
|
return res.json(404, {});
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ var DebugRoute = function(app) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.get('/mongo', function(req, res) {
|
app.get('/mongo', function(req, res) {
|
||||||
|
|
||||||
var db = require('./../database');
|
var db = require('./../database');
|
||||||
@@ -390,6 +389,12 @@ var DebugRoute = function(app) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get('/test', function(req, res) {
|
||||||
|
topics.pushUnreadCount();
|
||||||
|
res.send();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
133
src/topics.js
133
src/topics.js
@@ -17,7 +17,9 @@ var async = require('async'),
|
|||||||
notifications = require('./notifications'),
|
notifications = require('./notifications'),
|
||||||
feed = require('./feed'),
|
feed = require('./feed'),
|
||||||
favourites = require('./favourites'),
|
favourites = require('./favourites'),
|
||||||
meta = require('./meta');
|
meta = require('./meta')
|
||||||
|
|
||||||
|
websockets = require('./websockets');
|
||||||
|
|
||||||
|
|
||||||
(function(Topics) {
|
(function(Topics) {
|
||||||
@@ -91,7 +93,6 @@ var async = require('async'),
|
|||||||
Topics.markAsRead(tid, uid);
|
Topics.markAsRead(tid, uid);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
||||||
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
db.sortedSetAdd('categories:' + cid + ':tid', timestamp, tid);
|
||||||
db.incrObjectField('category:' + cid, 'topic_count');
|
db.incrObjectField('category:' + cid, 'topic_count');
|
||||||
@@ -109,6 +110,8 @@ var async = require('async'),
|
|||||||
// Auto-subscribe the post creator to the newly created topic
|
// Auto-subscribe the post creator to the newly created topic
|
||||||
threadTools.toggleFollow(tid, uid);
|
threadTools.toggleFollow(tid, uid);
|
||||||
|
|
||||||
|
Topics.pushUnreadCount();
|
||||||
|
|
||||||
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
|
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
|
||||||
topicData.unreplied = 1;
|
topicData.unreplied = 1;
|
||||||
|
|
||||||
@@ -303,36 +306,7 @@ var async = require('async'),
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Topics.getUnreadTopics = function(uid, start, stop, callback) {
|
Topics.getUnreadTids = function(uid, start, stop, callback) {
|
||||||
|
|
||||||
var unreadTopics = {
|
|
||||||
'category_name': 'Unread',
|
|
||||||
'show_sidebar': 'hidden',
|
|
||||||
'show_topic_button': 'hidden',
|
|
||||||
'show_markallread_button': 'show',
|
|
||||||
'no_topics_message': 'hidden',
|
|
||||||
'topic_row_size': 'col-md-12',
|
|
||||||
'topics': []
|
|
||||||
};
|
|
||||||
|
|
||||||
function noUnreadTopics() {
|
|
||||||
unreadTopics.no_topics_message = 'show';
|
|
||||||
unreadTopics.show_markallread_button = 'hidden';
|
|
||||||
callback(unreadTopics);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendUnreadTopics(topicIds) {
|
|
||||||
Topics.getTopicsByTids(topicIds, uid, function(topicData) {
|
|
||||||
unreadTopics.topics = topicData;
|
|
||||||
unreadTopics.nextStart = start + topicIds.length;
|
|
||||||
if (!topicData || topicData.length === 0)
|
|
||||||
unreadTopics.no_topics_message = 'show';
|
|
||||||
if (uid === 0 || topicData.length === 0)
|
|
||||||
unreadTopics.show_markallread_button = 'hidden';
|
|
||||||
callback(unreadTopics);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var unreadTids = [],
|
var unreadTids = [],
|
||||||
done = false;
|
done = false;
|
||||||
|
|
||||||
@@ -340,12 +314,11 @@ var async = require('async'),
|
|||||||
return unreadTids.length < 20 && !done;
|
return unreadTids.length < 20 && !done;
|
||||||
}
|
}
|
||||||
|
|
||||||
async.whilst(
|
async.whilst(continueCondition, function(callback) {
|
||||||
continueCondition,
|
RDB.zrevrange('topics:recent', start, stop, function(err, tids) {
|
||||||
function(callback) {
|
if (err) {
|
||||||
db.getSortedSetRevRange('topics:recent', start, stop, function(err, tids) {
|
|
||||||
if (err)
|
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
if (tids && !tids.length) {
|
if (tids && !tids.length) {
|
||||||
done = true;
|
done = true;
|
||||||
@@ -373,18 +346,80 @@ var async = require('async'),
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}, function(err) {
|
||||||
function(err) {
|
callback(err, unreadTids);
|
||||||
if (err)
|
});
|
||||||
return callback([]);
|
};
|
||||||
if (unreadTids.length)
|
|
||||||
sendUnreadTopics(unreadTids);
|
|
||||||
else
|
|
||||||
noUnreadTopics();
|
|
||||||
|
|
||||||
|
Topics.getUnreadTopics = function(uid, start, stop, callback) {
|
||||||
|
var unreadTopics = {
|
||||||
|
'category_name': 'Unread',
|
||||||
|
'show_sidebar': 'hidden',
|
||||||
|
'show_topic_button': 'hidden',
|
||||||
|
'show_markallread_button': 'show',
|
||||||
|
'no_topics_message': 'hidden',
|
||||||
|
'topic_row_size': 'col-md-12',
|
||||||
|
'topics': []
|
||||||
|
};
|
||||||
|
|
||||||
|
function noUnreadTopics() {
|
||||||
|
unreadTopics.no_topics_message = 'show';
|
||||||
|
unreadTopics.show_markallread_button = 'hidden';
|
||||||
|
callback(unreadTopics);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
function sendUnreadTopics(topicIds) {
|
||||||
|
Topics.getTopicsByTids(topicIds, uid, function(topicData) {
|
||||||
|
unreadTopics.topics = topicData;
|
||||||
|
unreadTopics.nextStart = start + topicIds.length;
|
||||||
|
if (!topicData || topicData.length === 0) {
|
||||||
|
unreadTopics.no_topics_message = 'show';
|
||||||
}
|
}
|
||||||
|
if (uid === 0 || topicData.length === 0) {
|
||||||
|
unreadTopics.show_markallread_button = 'hidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(unreadTopics);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Topics.getUnreadTids(uid, start, stop, function(err, unreadTids) {
|
||||||
|
if (err) {
|
||||||
|
return callback([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unreadTids.length) {
|
||||||
|
sendUnreadTopics(unreadTids);
|
||||||
|
} else {
|
||||||
|
noUnreadTopics();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Topics.pushUnreadCount = function(uids, callback) {
|
||||||
|
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);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err) {
|
||||||
|
winston.error(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Topics.getTopicsByTids = function(tids, current_user, callback, category_id) {
|
Topics.getTopicsByTids = function(tids, current_user, callback, category_id) {
|
||||||
|
|
||||||
@@ -489,14 +524,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) {
|
threadTools.exists(tid, function(exists) {
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return callback(new Error('Topic tid \'' + tid + '\' not found'));
|
return callback(new Error('Topic tid \'' + tid + '\' not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "quiet" is used for things like RSS feed updating, HTML parsing for non-js users, etc
|
||||||
|
if (!quiet) {
|
||||||
Topics.markAsRead(tid, current_user);
|
Topics.markAsRead(tid, current_user);
|
||||||
|
Topics.pushUnreadCount(current_user);
|
||||||
Topics.increaseViewCount(tid);
|
Topics.increaseViewCount(tid);
|
||||||
|
}
|
||||||
|
|
||||||
function getTopicData(next) {
|
function getTopicData(next) {
|
||||||
Topics.getTopicData(tid, next);
|
Topics.getTopicData(tid, next);
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ var path = require('path'),
|
|||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
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) {
|
||||||
if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) {
|
if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) {
|
||||||
return next(new Error('Topic deleted'), null);
|
return next(new Error('Topic deleted'), null);
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ websockets.init = function(io) {
|
|||||||
var hs = socket.handshake,
|
var hs = socket.handshake,
|
||||||
sessionID, uid, lastPostTime = 0;
|
sessionID, uid, lastPostTime = 0;
|
||||||
|
|
||||||
|
|
||||||
// Validate the session, if present
|
// Validate the session, if present
|
||||||
socketCookieParser(hs, {}, function(err) {
|
socketCookieParser(hs, {}, function(err) {
|
||||||
sessionID = socket.handshake.signedCookies["express.sid"];
|
sessionID = socket.handshake.signedCookies["express.sid"];
|
||||||
@@ -104,8 +103,6 @@ websockets.init = function(io) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
socket.on('disconnect', function() {
|
socket.on('disconnect', function() {
|
||||||
|
|
||||||
var index = userSockets[uid].indexOf(socket);
|
var index = userSockets[uid].indexOf(socket);
|
||||||
@@ -868,6 +865,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) {
|
socket.on('api:category.loadMore', function(data, callback) {
|
||||||
var start = data.after,
|
var start = data.after,
|
||||||
end = start + 9;
|
end = start + 9;
|
||||||
@@ -1137,6 +1140,10 @@ websockets.init = function(io) {
|
|||||||
websockets.in = function(room) {
|
websockets.in = function(room) {
|
||||||
return io.sockets.in(room);
|
return io.sockets.in(room);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
websockets.getConnectedClients = function() {
|
||||||
|
return userSockets;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})(module.exports);
|
})(module.exports);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user