diff --git a/public/src/app.js b/public/src/app.js index 585ce34484..e2783f17b2 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -112,7 +112,13 @@ app.cacheBuster = null; * config (obj) * next (string) */ - require(['benchpress', 'translator', 'forum/header/notifications', 'forum/header/chat'], function (Benchpress, translator, Notifications, Chat) { + require([ + 'benchpress', + 'translator', + 'forum/unread', + 'forum/header/notifications', + 'forum/header/chat', + ], function (Benchpress, translator, Unread, Notifications, Chat) { app.user = data.header.user; data.header.config = data.config; config = data.config; @@ -136,7 +142,7 @@ app.cacheBuster = null; Object.values(toRender).forEach(function (element, idx) { element.html(html[idx]); }); - + Unread.initUnreadTopics(); Notifications.prepareDOM(); Chat.prepareDOM(); app.reskin(data.config.bootswatchSkin); diff --git a/public/src/client/footer.js b/public/src/client/footer.js index 73c6a775f2..7f016be5a7 100644 --- a/public/src/client/footer.js +++ b/public/src/client/footer.js @@ -4,101 +4,21 @@ define('forum/footer', [ 'components', 'translator', + 'forum/unread', 'forum/header/notifications', 'forum/header/chat', -], function (components, translator, Notifications, Chat) { +], function (components, translator, Unread, Notifications, Chat) { Notifications.prepareDOM(); Chat.prepareDOM(); translator.prepareDOM(); - function updateUnreadTopicCount(url, count) { - if (!utils.isNumber(count)) { - return; - } - $('a[href="' + config.relative_path + url + '"].navigation-link i') - .toggleClass('unread-count', count > 0) - .attr('data-content', count > 99 ? '99+' : count); - } - - function updateUnreadChatCount(count) { + socket.on('event:unread.updateChatCount', function (count) { components.get('chat/icon') .toggleClass('unread-count', count > 0) .attr('data-content', count > 99 ? '99+' : count); - } - - function initUnreadTopics() { - var unreadTopics = {}; - - function onNewPost(data) { - if (data && data.posts && data.posts.length) { - var post = data.posts[0]; - - if (parseInt(post.uid, 10) !== parseInt(app.user.uid, 10) && !unreadTopics[post.topic.tid]) { - increaseUnreadCount(data); - markTopicsUnread(post.topic.tid); - unreadTopics[post.topic.tid] = true; - } - } - } - - function increaseUnreadCount(data) { - var post = data.posts[0]; - - var unreadTopicCount = parseInt($('a[href="' + config.relative_path + '/unread"].navigation-link i').attr('data-content'), 10) + 1; - updateUnreadTopicCount('/unread', unreadTopicCount); - - var isNewTopic = post.isMain && parseInt(post.uid, 10) !== parseInt(app.user.uid, 10); - if (isNewTopic) { - var unreadNewTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=new"].navigation-link i').attr('data-content'), 10) + 1; - updateUnreadTopicCount('/unread?filter=new', unreadNewTopicCount); - } - - var isUnreplied = parseInt(post.topic.postcount, 10) <= 1; - if (isUnreplied) { - var unreadUnrepliedTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=unreplied"].navigation-link i').attr('data-content'), 10) + 1; - updateUnreadTopicCount('/unread?filter=unreplied', unreadUnrepliedTopicCount); - } - if ($('a[href="' + config.relative_path + '/unread?filter=watched"].navigation-link i').length) { - socket.emit('topics.isFollowed', post.topic.tid, function (err, isFollowed) { - if (err) { - return app.alertError(err.message); - } - if (isFollowed) { - var unreadWatchedTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=watched"].navigation-link i').attr('data-content'), 10) + 1; - updateUnreadTopicCount('/unread?filter=watched', unreadWatchedTopicCount); - } - }); - } - } - - function markTopicsUnread(tid) { - $('[data-tid="' + tid + '"]').addClass('unread'); - } - - $(window).on('action:ajaxify.end', function (ev, data) { - if (data.url) { - var tid = data.url.match(/^topic\/(\d+)/); - - if (tid && tid[1]) { - delete unreadTopics[tid[1]]; - } - } - }); - - socket.on('event:new_post', onNewPost); - } - - function updateUnreadCounters(data) { - updateUnreadTopicCount('/unread', data.unreadTopicCount); - updateUnreadTopicCount('/unread?filter=new', data.unreadNewTopicCount); - updateUnreadTopicCount('/unread?filter=watched', data.unreadWatchedTopicCount); - updateUnreadTopicCount('/unread?filter=unreplied', data.unreadUnrepliedTopicCount); - } - - socket.on('event:unread.updateCount', updateUnreadCounters); - socket.on('event:unread.updateChatCount', updateUnreadChatCount); + }); if (app.user.uid > 0) { - initUnreadTopics(); + Unread.initUnreadTopics(); } }); diff --git a/public/src/client/unread.js b/public/src/client/unread.js index 09278b88de..9df088a16f 100644 --- a/public/src/client/unread.js +++ b/public/src/client/unread.js @@ -10,6 +10,8 @@ define('forum/unread', ['topicSelect', 'components', 'topicList'], function (top topicList.init('unread'); topicSelect.init(); + updateUnreadTopicCount('/' + ajaxify.data.selectedFilter.url, ajaxify.data.topicCount); + $('#markSelectedRead').on('click', function () { var tids = topicSelect.getSelectedTids(); if (!tids.length) { @@ -77,6 +79,81 @@ define('forum/unread', ['topicSelect', 'components', 'topicList'], function (top } } + function updateUnreadTopicCount(url, count) { + if (!utils.isNumber(count)) { + return; + } + + $('a[href="' + config.relative_path + url + '"].navigation-link i') + .toggleClass('unread-count', count > 0) + .attr('data-content', count > 99 ? '99+' : count); + } + + Unread.initUnreadTopics = function () { + var unreadTopics = {}; + + function onNewPost(data) { + if (data && data.posts && data.posts.length) { + var post = data.posts[0]; + + if (parseInt(post.uid, 10) !== parseInt(app.user.uid, 10) && !unreadTopics[post.topic.tid]) { + increaseUnreadCount(post); + markTopicsUnread(post.topic.tid); + unreadTopics[post.topic.tid] = true; + } + } + } + + function increaseUnreadCount(post) { + var unreadTopicCount = parseInt($('a[href="' + config.relative_path + '/unread"].navigation-link i').attr('data-content'), 10) + 1; + updateUnreadTopicCount('/unread', unreadTopicCount); + + var isNewTopic = post.isMain && parseInt(post.uid, 10) !== parseInt(app.user.uid, 10); + if (isNewTopic) { + var unreadNewTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=new"].navigation-link i').attr('data-content'), 10) + 1; + updateUnreadTopicCount('/unread?filter=new', unreadNewTopicCount); + } + + var isUnreplied = parseInt(post.topic.postcount, 10) <= 1; + if (isUnreplied) { + var unreadUnrepliedTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=unreplied"].navigation-link i').attr('data-content'), 10) + 1; + updateUnreadTopicCount('/unread?filter=unreplied', unreadUnrepliedTopicCount); + } + if ($('a[href="' + config.relative_path + '/unread?filter=watched"].navigation-link i').length) { + socket.emit('topics.isFollowed', post.topic.tid, function (err, isFollowed) { + if (err) { + return app.alertError(err.message); + } + if (isFollowed) { + var unreadWatchedTopicCount = parseInt($('a[href="' + config.relative_path + '/unread?filter=watched"].navigation-link i').attr('data-content'), 10) + 1; + updateUnreadTopicCount('/unread?filter=watched', unreadWatchedTopicCount); + } + }); + } + } + + function markTopicsUnread(tid) { + $('[data-tid="' + tid + '"]').addClass('unread'); + } + + $(window).on('action:ajaxify.end', function () { + if (ajaxify.data.template.topic) { + delete unreadTopics[ajaxify.data.tid]; + } + }); + socket.removeListener('event:new_post', onNewPost); + socket.on('event:new_post', onNewPost); + + socket.removeListener('event:unread.updateCount', updateUnreadCounters); + socket.on('event:unread.updateCount', updateUnreadCounters); + }; + + function updateUnreadCounters(data) { + updateUnreadTopicCount('/unread', data.unreadTopicCount); + updateUnreadTopicCount('/unread?filter=new', data.unreadNewTopicCount); + updateUnreadTopicCount('/unread?filter=watched', data.unreadWatchedTopicCount); + updateUnreadTopicCount('/unread?filter=unreplied', data.unreadUnrepliedTopicCount); + } return Unread; }); diff --git a/public/src/modules/topicList.js b/public/src/modules/topicList.js index a6399d6087..56219fec14 100644 --- a/public/src/modules/topicList.js +++ b/public/src/modules/topicList.js @@ -83,7 +83,7 @@ define('topicList', [ }; function onNewTopic(data) { - if ((ajaxify.data.selectedCids && ajaxify.data.selectedCids.indexOf(parseInt(data.cid, 10)) === -1) || + if ((ajaxify.data.selectedCids && ajaxify.data.selectedCids.length && ajaxify.data.selectedCids.indexOf(parseInt(data.cid, 10)) === -1) || (ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched') || (ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10))) { return; diff --git a/src/groups/membership.js b/src/groups/membership.js index 9631bb4a6a..bfce9947de 100644 --- a/src/groups/membership.js +++ b/src/groups/membership.js @@ -77,7 +77,7 @@ module.exports = function (Groups) { }; function inviteOrRequestMembership(groupName, uid, type, callback) { - if (!parseInt(uid, 10)) { + if (!(parseInt(uid, 10) > 0)) { return callback(new Error('[[error:not-logged-in]]')); } var hookName = type === 'invite' ? 'action:group.inviteMember' : 'action:group.requestMembership'; diff --git a/src/topics/unread.js b/src/topics/unread.js index 5e02e2e686..ab07395171 100644 --- a/src/topics/unread.js +++ b/src/topics/unread.js @@ -215,26 +215,26 @@ module.exports = function (Topics) { if (topic && topic.cid && cidMatch(topic.cid) && !blockedUids.includes(parseInt(topic.uid, 10))) { topic.tid = parseInt(topic.tid, 10); if ((results.isTopicsFollowed[index] || !isCidIgnored[topic.cid])) { - counts[''] += 1; tidsByFilter[''].push(topic.tid); } if (results.isTopicsFollowed[index]) { - counts.watched += 1; tidsByFilter.watched.push(topic.tid); } if (topic.postcount <= 1) { - counts.unreplied += 1; tidsByFilter.unreplied.push(topic.tid); } if (!userRead[topic.tid]) { - counts.new += 1; tidsByFilter.new.push(topic.tid); } } }); + counts[''] = tidsByFilter[''].length; + counts.watched = tidsByFilter.watched.length; + counts.unreplied = tidsByFilter.unreplied.length; + counts.new = tidsByFilter.new.length; next(null, { counts: counts, @@ -439,10 +439,8 @@ module.exports = function (Topics) { }; Topics.hasReadTopics = function (tids, uid, callback) { - if (!parseInt(uid, 10)) { - return callback(null, tids.map(function () { - return false; - })); + if (!(parseInt(uid, 10) > 0)) { + return setImmediate(callback, null, tids.map(() => false)); } async.waterfall([