mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 01:56:12 +01:00
Recent refactor (#6879)
* wip * fix inf scroll * remove duplicated code * remove dupe code in /unread * use topicList * update tag page to use topicList * fix tests * combine ifs * remove more dupe code * disable timeout
This commit is contained in:
committed by
GitHub
parent
aa301f27a1
commit
c27be9db5a
@@ -1,18 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
define('forum/category', [
|
define('forum/category', [
|
||||||
'forum/infinitescroll',
|
'forum/infinitescroll',
|
||||||
'share',
|
'share',
|
||||||
'navigator',
|
'navigator',
|
||||||
'forum/category/tools',
|
'forum/category/tools',
|
||||||
'forum/recent',
|
'topicList',
|
||||||
'sort',
|
'sort',
|
||||||
'components',
|
], function (infinitescroll, share, navigator, categoryTools, topicList, sort) {
|
||||||
'translator',
|
|
||||||
'topicSelect',
|
|
||||||
'handleBack',
|
|
||||||
], function (infinitescroll, share, navigator, categoryTools, recent, sort, components, translator, topicSelect, handleBack) {
|
|
||||||
var Category = {};
|
var Category = {};
|
||||||
|
|
||||||
$(window).on('action:ajaxify.start', function (ev, data) {
|
$(window).on('action:ajaxify.start', function (ev, data) {
|
||||||
@@ -25,7 +20,7 @@ define('forum/category', [
|
|||||||
|
|
||||||
function removeListeners() {
|
function removeListeners() {
|
||||||
categoryTools.removeListeners();
|
categoryTools.removeListeners();
|
||||||
recent.removeListeners();
|
topicList.removeListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Category.init = function () {
|
Category.init = function () {
|
||||||
@@ -36,15 +31,16 @@ define('forum/category', [
|
|||||||
share.addShareHandlers(ajaxify.data.name);
|
share.addShareHandlers(ajaxify.data.name);
|
||||||
|
|
||||||
categoryTools.init(cid);
|
categoryTools.init(cid);
|
||||||
recent.watchForNewPosts();
|
|
||||||
|
topicList.init('category', loadTopicsAfter);
|
||||||
|
|
||||||
sort.handleSort('categoryTopicSort', 'user.setCategorySort', 'category/' + ajaxify.data.slug);
|
sort.handleSort('categoryTopicSort', 'user.setCategorySort', 'category/' + ajaxify.data.slug);
|
||||||
|
|
||||||
enableInfiniteLoadingOrPagination();
|
if (!config.usePagination) {
|
||||||
|
navigator.init('[component="category/topic"]', ajaxify.data.topic_count, Category.toTop, Category.toBottom, Category.navigatorCallback);
|
||||||
handleBack.init(function (after, cb) {
|
} else {
|
||||||
loadTopicsAfter(after, 1, cb);
|
navigator.disable();
|
||||||
});
|
}
|
||||||
|
|
||||||
handleScrollToTopicIndex();
|
handleScrollToTopicIndex();
|
||||||
|
|
||||||
@@ -104,32 +100,8 @@ define('forum/category', [
|
|||||||
return bottomIndex;
|
return bottomIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
function enableInfiniteLoadingOrPagination() {
|
|
||||||
if (!config.usePagination) {
|
|
||||||
navigator.init('[component="category/topic"]', ajaxify.data.topic_count, Category.toTop, Category.toBottom, Category.navigatorCallback);
|
|
||||||
infinitescroll.init($('[component="category"]'), Category.loadMoreTopics);
|
|
||||||
} else {
|
|
||||||
navigator.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Category.loadMoreTopics = function (direction) {
|
|
||||||
if (!$('[component="category"]').length || !$('[component="category"]').children().length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var topics = $('[component="category/topic"]');
|
|
||||||
var afterEl = direction > 0 ? topics.last() : topics.first();
|
|
||||||
var after = (parseInt(afterEl.attr('data-index'), 10) || 0) + (direction > 0 ? 1 : 0);
|
|
||||||
|
|
||||||
loadTopicsAfter(after, direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadTopicsAfter(after, direction, callback) {
|
function loadTopicsAfter(after, direction, callback) {
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
if (!utils.isNumber(after) || (after === 0 && components.get('category/topic', 'index', 0).length)) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).trigger('action:category.loading');
|
$(window).trigger('action:category.loading');
|
||||||
var params = utils.params();
|
var params = utils.params();
|
||||||
@@ -140,78 +112,10 @@ define('forum/category', [
|
|||||||
query: params,
|
query: params,
|
||||||
categoryTopicSort: config.categoryTopicSort,
|
categoryTopicSort: config.categoryTopicSort,
|
||||||
}, function (data, done) {
|
}, function (data, done) {
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
Category.onTopicsLoaded(data, direction, done);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).trigger('action:category.loaded');
|
$(window).trigger('action:category.loaded');
|
||||||
callback();
|
callback(data, done);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Category.onTopicsLoaded = function (data, direction, callback) {
|
|
||||||
if (!data || !data.topics.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeAlreadyAddedTopics(topics) {
|
|
||||||
return topics.filter(function (topic) {
|
|
||||||
return components.get('category/topic', 'tid', topic.tid).length === 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
data.topics = removeAlreadyAddedTopics(data.topics);
|
|
||||||
if (!data.topics.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
data.showSelect = data.privileges.editable;
|
|
||||||
|
|
||||||
var after;
|
|
||||||
var before;
|
|
||||||
var topics = $('[component="category/topic"]');
|
|
||||||
|
|
||||||
if (direction > 0 && topics.length) {
|
|
||||||
after = topics.last();
|
|
||||||
} else if (direction < 0 && topics.length) {
|
|
||||||
before = topics.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.parseAndTranslate('category', 'topics', data, function (html) {
|
|
||||||
$('[component="category"]').removeClass('hidden');
|
|
||||||
$('.category-sidebar').removeClass('hidden');
|
|
||||||
|
|
||||||
$('#category-no-topics').remove();
|
|
||||||
|
|
||||||
if (after) {
|
|
||||||
html.insertAfter(after);
|
|
||||||
} else if (before) {
|
|
||||||
var height = $(document).height();
|
|
||||||
var scrollTop = $(window).scrollTop();
|
|
||||||
|
|
||||||
html.insertBefore(before);
|
|
||||||
|
|
||||||
$(window).scrollTop(scrollTop + ($(document).height() - height));
|
|
||||||
} else {
|
|
||||||
$('[component="category"]').append(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!topicSelect.getSelectedTids().length) {
|
|
||||||
infinitescroll.removeExtra($('[component="category/topic"]'), direction, config.topicsPerPage * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
html.find('.timeago').timeago();
|
|
||||||
app.createUserTooltips();
|
|
||||||
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
|
||||||
|
|
||||||
$(window).trigger('action:topics.loaded', { topics: data.topics });
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Category;
|
return Category;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ define('forum/infinitescroll', function () {
|
|||||||
callback = cb;
|
callback = cb;
|
||||||
container = el || $('body');
|
container = el || $('body');
|
||||||
}
|
}
|
||||||
|
previousScrollTop = $(window).scrollTop();
|
||||||
$(window).off('scroll', onScroll).on('scroll', onScroll);
|
$(window).off('scroll', onScroll).on('scroll', onScroll);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'], function (recent, components, infinitescroll) {
|
define('forum/popular', ['topicList'], function (topicList) {
|
||||||
var Popular = {};
|
var Popular = {};
|
||||||
|
|
||||||
Popular.init = function () {
|
Popular.init = function () {
|
||||||
app.enterRoom('popular_topics');
|
app.enterRoom('popular_topics');
|
||||||
|
|
||||||
recent.handleCategorySelection();
|
topicList.init('popular');
|
||||||
|
|
||||||
if (!config.usePagination) {
|
|
||||||
infinitescroll.init(loadMoreTopics);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadMoreTopics(direction) {
|
|
||||||
if (direction < 0 || !$('[component="category"]').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var query = utils.params();
|
|
||||||
infinitescroll.loadMore('topics.loadMorePopularTopics', {
|
|
||||||
after: $('[component="category"]').attr('data-nextstart'),
|
|
||||||
count: config.topicsPerPage,
|
|
||||||
cid: query.cid,
|
|
||||||
query: query,
|
|
||||||
term: ajaxify.data.selectedTerm.term,
|
|
||||||
filter: ajaxify.data.selectedFilter.filter,
|
|
||||||
}, function (data, done) {
|
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
recent.onTopicsLoaded('popular', data.topics, false, direction, done);
|
|
||||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Popular;
|
return Popular;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,268 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define('forum/recent', ['forum/infinitescroll', 'components', 'handleBack'], function (infinitescroll, components, handleBack) {
|
define('forum/recent', ['topicList'], function (topicList) {
|
||||||
var Recent = {};
|
var Recent = {};
|
||||||
|
|
||||||
var newTopicCount = 0;
|
|
||||||
var newPostCount = 0;
|
|
||||||
|
|
||||||
$(window).on('action:ajaxify.start', function (ev, data) {
|
|
||||||
if (ajaxify.currentPage !== data.url) {
|
|
||||||
Recent.removeListeners();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Recent.init = function () {
|
Recent.init = function () {
|
||||||
app.enterRoom('recent_topics');
|
app.enterRoom('recent_topics');
|
||||||
|
|
||||||
Recent.watchForNewPosts();
|
topicList.init('recent');
|
||||||
|
|
||||||
Recent.handleCategorySelection();
|
|
||||||
|
|
||||||
handleBack.init(function (after, cb) {
|
|
||||||
loadTopicsAfter(after, 1, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#new-topics-alert').on('click', function () {
|
|
||||||
$(this).addClass('hide');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!config.usePagination) {
|
|
||||||
infinitescroll.init(Recent.loadMoreTopics);
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
|
|
||||||
};
|
|
||||||
|
|
||||||
Recent.watchForNewPosts = function () {
|
|
||||||
newPostCount = 0;
|
|
||||||
newTopicCount = 0;
|
|
||||||
Recent.removeListeners();
|
|
||||||
socket.on('event:new_topic', onNewTopic);
|
|
||||||
socket.on('event:new_post', onNewPost);
|
|
||||||
};
|
|
||||||
|
|
||||||
function onNewTopic(data) {
|
|
||||||
if (ajaxify.data.selectedCids && ajaxify.data.selectedCids.indexOf(parseInt(data.cid, 10)) === -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(data.cid, 10)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newTopicCount += 1;
|
|
||||||
Recent.updateAlertText();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onNewPost(data) {
|
|
||||||
function showAlert() {
|
|
||||||
newPostCount += 1;
|
|
||||||
Recent.updateAlertText();
|
|
||||||
}
|
|
||||||
|
|
||||||
var post = data.posts[0];
|
|
||||||
if (!post || !post.topic) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (parseInt(post.topic.mainPid, 10) === parseInt(post.pid, 10)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.selectedCids && ajaxify.data.selectedCids.indexOf(parseInt(post.topic.cid, 10)) === -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'new') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 10)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched') {
|
|
||||||
socket.emit('topics.isFollowed', post.tid, function (err, isFollowed) {
|
|
||||||
if (err) {
|
|
||||||
app.alertError(err.message);
|
|
||||||
}
|
|
||||||
if (isFollowed) {
|
|
||||||
showAlert();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showAlert();
|
|
||||||
}
|
|
||||||
|
|
||||||
Recent.handleCategorySelection = function () {
|
|
||||||
function getSelectedCids() {
|
|
||||||
var cids = [];
|
|
||||||
$('[component="category/list"] [data-cid]').each(function (index, el) {
|
|
||||||
if ($(el).find('i.fa-check').length) {
|
|
||||||
cids.push(parseInt($(el).attr('data-cid'), 10));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cids.sort(function (a, b) {
|
|
||||||
return a - b;
|
|
||||||
});
|
|
||||||
return cids;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('[component="category/dropdown"]').on('hidden.bs.dropdown', function () {
|
|
||||||
var cids = getSelectedCids();
|
|
||||||
var changed = ajaxify.data.selectedCids.length !== cids.length;
|
|
||||||
ajaxify.data.selectedCids.forEach(function (cid, index) {
|
|
||||||
if (cid !== cids[index]) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
var url = window.location.pathname;
|
|
||||||
var currentParams = utils.params();
|
|
||||||
if (cids.length) {
|
|
||||||
currentParams.cid = cids;
|
|
||||||
url += '?' + decodeURIComponent($.param(currentParams));
|
|
||||||
}
|
|
||||||
ajaxify.go(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('[component="category/list"]').on('click', '[data-cid]', function (ev) {
|
|
||||||
function selectChildren(parentCid, flag) {
|
|
||||||
$('[component="category/list"] [data-parent-cid="' + parentCid + '"] [component="category/select/icon"]').toggleClass('fa-check', flag);
|
|
||||||
$('[component="category/list"] [data-parent-cid="' + parentCid + '"]').each(function (index, el) {
|
|
||||||
selectChildren($(el).attr('data-cid'), flag);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var categoryEl = $(this);
|
|
||||||
var cid = $(this).attr('data-cid');
|
|
||||||
if (ev.ctrlKey) {
|
|
||||||
selectChildren(cid, !categoryEl.find('[component="category/select/icon"]').hasClass('fa-check'));
|
|
||||||
}
|
|
||||||
categoryEl.find('[component="category/select/icon"]').toggleClass('fa-check');
|
|
||||||
$('[component="category/list"] li').first().find('i').toggleClass('fa-check', !getSelectedCids().length);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Recent.removeListeners = function () {
|
|
||||||
socket.removeListener('event:new_topic', onNewTopic);
|
|
||||||
socket.removeListener('event:new_post', onNewPost);
|
|
||||||
};
|
|
||||||
|
|
||||||
Recent.updateAlertText = function () {
|
|
||||||
var text = '';
|
|
||||||
|
|
||||||
if (newTopicCount === 0) {
|
|
||||||
if (newPostCount === 1) {
|
|
||||||
text = '[[recent:there-is-a-new-post]]';
|
|
||||||
} else if (newPostCount > 1) {
|
|
||||||
text = '[[recent:there-are-new-posts, ' + newPostCount + ']]';
|
|
||||||
}
|
|
||||||
} else if (newTopicCount === 1) {
|
|
||||||
if (newPostCount === 0) {
|
|
||||||
text = '[[recent:there-is-a-new-topic]]';
|
|
||||||
} else if (newPostCount === 1) {
|
|
||||||
text = '[[recent:there-is-a-new-topic-and-a-new-post]]';
|
|
||||||
} else if (newPostCount > 1) {
|
|
||||||
text = '[[recent:there-is-a-new-topic-and-new-posts, ' + newPostCount + ']]';
|
|
||||||
}
|
|
||||||
} else if (newTopicCount > 1) {
|
|
||||||
if (newPostCount === 0) {
|
|
||||||
text = '[[recent:there-are-new-topics, ' + newTopicCount + ']]';
|
|
||||||
} else if (newPostCount === 1) {
|
|
||||||
text = '[[recent:there-are-new-topics-and-a-new-post, ' + newTopicCount + ']]';
|
|
||||||
} else if (newPostCount > 1) {
|
|
||||||
text = '[[recent:there-are-new-topics-and-new-posts, ' + newTopicCount + ', ' + newPostCount + ']]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
text += ' [[recent:click-here-to-reload]]';
|
|
||||||
|
|
||||||
$('#new-topics-alert').translateText(text).removeClass('hide').fadeIn('slow');
|
|
||||||
$('#category-no-topics').addClass('hide');
|
|
||||||
};
|
|
||||||
|
|
||||||
Recent.loadMoreTopics = function (direction) {
|
|
||||||
if (!$('[component="category"]').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var topics = $('[component="category/topic"]');
|
|
||||||
var afterEl = direction > 0 ? topics.last() : topics.first();
|
|
||||||
var after = (parseInt(afterEl.attr('data-index'), 10) || 0) + (direction > 0 ? 1 : 0);
|
|
||||||
loadTopicsAfter(after, direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadTopicsAfter(after, direction, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
var query = utils.params();
|
|
||||||
infinitescroll.loadMore('topics.loadMoreRecentTopics', {
|
|
||||||
after: after,
|
|
||||||
direction: direction,
|
|
||||||
count: config.topicsPerPage,
|
|
||||||
cid: query.cid,
|
|
||||||
query: query,
|
|
||||||
filter: ajaxify.data.selectedFilter.filter,
|
|
||||||
set: $('[component="category"]').attr('data-set') ? $('[component="category"]').attr('data-set') : 'topics:recent',
|
|
||||||
}, function (data, done) {
|
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
Recent.onTopicsLoaded('recent', data.topics, false, direction, done);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Recent.onTopicsLoaded = function (templateName, topics, showSelect, direction, callback) {
|
|
||||||
topics = topics.filter(function (topic) {
|
|
||||||
return !components.get('category/topic', 'tid', topic.tid).length;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!topics.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
var after;
|
|
||||||
var before;
|
|
||||||
var topicsList = $('[component="category/topic"]');
|
|
||||||
|
|
||||||
if (direction > 0 && topics.length) {
|
|
||||||
after = topicsList.last();
|
|
||||||
} else if (direction < 0 && topics.length) {
|
|
||||||
before = topicsList.first();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.parseAndTranslate(templateName, 'topics', { topics: topics, showSelect: showSelect }, function (html) {
|
|
||||||
$('#category-no-topics').remove();
|
|
||||||
|
|
||||||
if (after && after.length) {
|
|
||||||
html.insertAfter(after);
|
|
||||||
} else if (before && before.length) {
|
|
||||||
var height = $(document).height();
|
|
||||||
var scrollTop = $(window).scrollTop();
|
|
||||||
|
|
||||||
html.insertBefore(before);
|
|
||||||
|
|
||||||
$(window).scrollTop(scrollTop + ($(document).height() - height));
|
|
||||||
} else {
|
|
||||||
$('[component="category"]').append(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
html.find('.timeago').timeago();
|
|
||||||
app.createUserTooltips();
|
|
||||||
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
|
||||||
$(window).trigger('action:topics.loaded', { topics: topics });
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Recent;
|
return Recent;
|
||||||
|
|||||||
@@ -1,42 +1,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) {
|
define('forum/tag', ['topicList', 'forum/infinitescroll'], function (topicList, infinitescroll) {
|
||||||
var Tag = {};
|
var Tag = {};
|
||||||
|
|
||||||
Tag.init = function () {
|
Tag.init = function () {
|
||||||
app.enterRoom('tags');
|
app.enterRoom('tags');
|
||||||
|
|
||||||
if ($('body').height() <= $(window).height() && $('[component="category"]').children().length >= 20) {
|
topicList.init('tag', loadMoreTopics);
|
||||||
$('#load-more-btn').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#load-more-btn').on('click', function () {
|
|
||||||
loadMoreTopics();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!config.usePagination) {
|
|
||||||
infinitescroll.init(loadMoreTopics);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMoreTopics(direction) {
|
|
||||||
if (direction < 0 || !$('[component="category"]').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function loadMoreTopics(after, direction, callback) {
|
||||||
infinitescroll.loadMore('topics.loadMoreFromSet', {
|
infinitescroll.loadMore('topics.loadMoreFromSet', {
|
||||||
set: 'tag:' + ajaxify.data.tag + ':topics',
|
set: 'tag:' + ajaxify.data.tag + ':topics',
|
||||||
after: $('[component="category"]').attr('data-nextstart'),
|
after: after,
|
||||||
|
direction: direction,
|
||||||
count: config.topicsPerPage,
|
count: config.topicsPerPage,
|
||||||
}, function (data, done) {
|
}, callback);
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
recent.onTopicsLoaded('tag', data.topics, false, direction, done);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
$('#load-more-btn').hide();
|
|
||||||
}
|
|
||||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define('forum/top', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) {
|
define('forum/top', ['topicList'], function (topicList) {
|
||||||
var Top = {};
|
var Top = {};
|
||||||
|
|
||||||
$(window).on('action:ajaxify.start', function (ev, data) {
|
|
||||||
if (ajaxify.currentPage !== data.url) {
|
|
||||||
recent.removeListeners();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Top.init = function () {
|
Top.init = function () {
|
||||||
app.enterRoom('top_topics');
|
app.enterRoom('top_topics');
|
||||||
|
|
||||||
recent.watchForNewPosts();
|
topicList.init('top');
|
||||||
|
|
||||||
recent.handleCategorySelection();
|
|
||||||
|
|
||||||
$('#new-topics-alert').on('click', function () {
|
|
||||||
$(this).addClass('hide');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!config.usePagination) {
|
|
||||||
infinitescroll.init(loadMoreTopics);
|
|
||||||
}
|
|
||||||
|
|
||||||
$(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadMoreTopics(direction) {
|
|
||||||
if (direction < 0 || !$('[component="category"]').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var query = utils.params();
|
|
||||||
infinitescroll.loadMore('topics.loadMoreTopTopics', {
|
|
||||||
after: $('[component="category"]').attr('data-nextstart'),
|
|
||||||
count: config.topicsPerPage,
|
|
||||||
cid: query.cid,
|
|
||||||
query: query,
|
|
||||||
term: ajaxify.data.selectedTerm.term,
|
|
||||||
filter: ajaxify.data.selectedFilter.filter,
|
|
||||||
}, function (data, done) {
|
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
recent.onTopicsLoaded('top', data.topics, true, direction, done);
|
|
||||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
$('#load-more-btn').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Top;
|
return Top;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,27 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', 'components'], function (recent, topicSelect, infinitescroll, components) {
|
define('forum/unread', ['topicSelect', 'components', 'topicList'], function (topicSelect, components, topicList) {
|
||||||
var Unread = {};
|
var Unread = {};
|
||||||
|
|
||||||
$(window).on('action:ajaxify.start', function (ev, data) {
|
|
||||||
if (ajaxify.currentPage !== data.url) {
|
|
||||||
recent.removeListeners();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Unread.init = function () {
|
Unread.init = function () {
|
||||||
app.enterRoom('unread_topics');
|
app.enterRoom('unread_topics');
|
||||||
|
|
||||||
$('#new-topics-alert').on('click', function () {
|
topicList.init('unread');
|
||||||
$(this).addClass('hide');
|
topicSelect.init();
|
||||||
});
|
|
||||||
|
|
||||||
recent.watchForNewPosts();
|
|
||||||
|
|
||||||
recent.handleCategorySelection();
|
|
||||||
|
|
||||||
$(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
|
|
||||||
|
|
||||||
$('#markSelectedRead').on('click', function () {
|
$('#markSelectedRead').on('click', function () {
|
||||||
var tids = topicSelect.getSelectedTids();
|
var tids = topicSelect.getSelectedTids();
|
||||||
@@ -71,42 +58,6 @@ define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', '
|
|||||||
doneRemovingTids(tids);
|
doneRemovingTids(tids);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
topicSelect.init();
|
|
||||||
|
|
||||||
if ($('body').height() <= $(window).height() && $('[component="category"]').children().length >= 20) {
|
|
||||||
$('#load-more-btn').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#load-more-btn').on('click', function () {
|
|
||||||
loadMoreTopics();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!config.usePagination) {
|
|
||||||
infinitescroll.init(loadMoreTopics);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMoreTopics(direction) {
|
|
||||||
if (direction < 0 || !$('[component="category"]').length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var query = utils.params();
|
|
||||||
infinitescroll.loadMore('topics.loadMoreUnreadTopics', {
|
|
||||||
after: $('[component="category"]').attr('data-nextstart'),
|
|
||||||
count: config.topicsPerPage,
|
|
||||||
cid: query.cid,
|
|
||||||
query: query,
|
|
||||||
filter: ajaxify.data.selectedFilter.filter,
|
|
||||||
}, function (data, done) {
|
|
||||||
if (data.topics && data.topics.length) {
|
|
||||||
recent.onTopicsLoaded('unread', data.topics, true, direction, done);
|
|
||||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
$('#load-more-btn').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function doneRemovingTids(tids) {
|
function doneRemovingTids(tids) {
|
||||||
|
|||||||
290
public/src/modules/topicList.js
Normal file
290
public/src/modules/topicList.js
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
define('topicList', ['forum/infinitescroll', 'handleBack', 'topicSelect'], function (infinitescroll, handleBack, topicSelect) {
|
||||||
|
var TopicList = {};
|
||||||
|
var templateName = '';
|
||||||
|
|
||||||
|
var tplToSort = {
|
||||||
|
recent: 'recent',
|
||||||
|
unread: 'unread',
|
||||||
|
popular: 'posts',
|
||||||
|
top: 'votes',
|
||||||
|
};
|
||||||
|
|
||||||
|
var newTopicCount = 0;
|
||||||
|
var newPostCount = 0;
|
||||||
|
|
||||||
|
var loadTopicsCallback;
|
||||||
|
|
||||||
|
$(window).on('action:ajaxify.start', function () {
|
||||||
|
TopicList.removeListeners();
|
||||||
|
loadTopicsCallback = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
TopicList.init = function (template, cb) {
|
||||||
|
templateName = template;
|
||||||
|
loadTopicsCallback = cb;
|
||||||
|
|
||||||
|
TopicList.watchForNewPosts();
|
||||||
|
|
||||||
|
TopicList.handleCategorySelection();
|
||||||
|
|
||||||
|
if (!config.usePagination) {
|
||||||
|
infinitescroll.init(TopicList.loadMoreTopics);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBack.init(function (after, cb) {
|
||||||
|
loadTopicsAfter(after, 1, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('body').height() <= $(window).height() && $('[component="category"]').children().length >= 20) {
|
||||||
|
$('#load-more-btn').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#load-more-btn').on('click', function () {
|
||||||
|
TopicList.loadMoreTopics(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
|
||||||
|
};
|
||||||
|
|
||||||
|
TopicList.watchForNewPosts = function () {
|
||||||
|
$('#new-topics-alert').on('click', function () {
|
||||||
|
$(this).addClass('hide');
|
||||||
|
});
|
||||||
|
newPostCount = 0;
|
||||||
|
newTopicCount = 0;
|
||||||
|
TopicList.removeListeners();
|
||||||
|
socket.on('event:new_topic', onNewTopic);
|
||||||
|
socket.on('event:new_post', onNewPost);
|
||||||
|
};
|
||||||
|
|
||||||
|
TopicList.removeListeners = function () {
|
||||||
|
socket.removeListener('event:new_topic', onNewTopic);
|
||||||
|
socket.removeListener('event:new_post', onNewPost);
|
||||||
|
};
|
||||||
|
|
||||||
|
function onNewTopic(data) {
|
||||||
|
if ((ajaxify.data.selectedCids && 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTopicCount += 1;
|
||||||
|
updateAlertText();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onNewPost(data) {
|
||||||
|
function showAlert() {
|
||||||
|
newPostCount += 1;
|
||||||
|
updateAlertText();
|
||||||
|
}
|
||||||
|
|
||||||
|
var post = data.posts[0];
|
||||||
|
if ((!post || !post.topic) ||
|
||||||
|
(parseInt(post.topic.mainPid, 10) === parseInt(post.pid, 10)) ||
|
||||||
|
(ajaxify.data.selectedCids && ajaxify.data.selectedCids.indexOf(parseInt(post.topic.cid, 10)) === -1) ||
|
||||||
|
(ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'new') ||
|
||||||
|
(ajaxify.data.template.category && parseInt(ajaxify.data.cid, 10) !== parseInt(post.topic.cid, 10))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ajaxify.data.selectedFilter && ajaxify.data.selectedFilter.filter === 'watched') {
|
||||||
|
socket.emit('topics.isFollowed', post.tid, function (err, isFollowed) {
|
||||||
|
if (err) {
|
||||||
|
app.alertError(err.message);
|
||||||
|
}
|
||||||
|
if (isFollowed) {
|
||||||
|
showAlert();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showAlert();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAlertText() {
|
||||||
|
var text = '';
|
||||||
|
|
||||||
|
if (newTopicCount === 0) {
|
||||||
|
if (newPostCount === 1) {
|
||||||
|
text = '[[recent:there-is-a-new-post]]';
|
||||||
|
} else if (newPostCount > 1) {
|
||||||
|
text = '[[recent:there-are-new-posts, ' + newPostCount + ']]';
|
||||||
|
}
|
||||||
|
} else if (newTopicCount === 1) {
|
||||||
|
if (newPostCount === 0) {
|
||||||
|
text = '[[recent:there-is-a-new-topic]]';
|
||||||
|
} else if (newPostCount === 1) {
|
||||||
|
text = '[[recent:there-is-a-new-topic-and-a-new-post]]';
|
||||||
|
} else if (newPostCount > 1) {
|
||||||
|
text = '[[recent:there-is-a-new-topic-and-new-posts, ' + newPostCount + ']]';
|
||||||
|
}
|
||||||
|
} else if (newTopicCount > 1) {
|
||||||
|
if (newPostCount === 0) {
|
||||||
|
text = '[[recent:there-are-new-topics, ' + newTopicCount + ']]';
|
||||||
|
} else if (newPostCount === 1) {
|
||||||
|
text = '[[recent:there-are-new-topics-and-a-new-post, ' + newTopicCount + ']]';
|
||||||
|
} else if (newPostCount > 1) {
|
||||||
|
text = '[[recent:there-are-new-topics-and-new-posts, ' + newTopicCount + ', ' + newPostCount + ']]';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text += ' [[recent:click-here-to-reload]]';
|
||||||
|
|
||||||
|
$('#new-topics-alert').translateText(text).removeClass('hide').fadeIn('slow');
|
||||||
|
$('#category-no-topics').addClass('hide');
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicList.handleCategorySelection = function () {
|
||||||
|
function getSelectedCids() {
|
||||||
|
var cids = [];
|
||||||
|
$('[component="category/list"] [data-cid]').each(function (index, el) {
|
||||||
|
if ($(el).find('i.fa-check').length) {
|
||||||
|
cids.push(parseInt($(el).attr('data-cid'), 10));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cids.sort(function (a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
return cids;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('[component="category/dropdown"]').on('hidden.bs.dropdown', function () {
|
||||||
|
var cids = getSelectedCids();
|
||||||
|
var changed = ajaxify.data.selectedCids.length !== cids.length;
|
||||||
|
ajaxify.data.selectedCids.forEach(function (cid, index) {
|
||||||
|
if (cid !== cids[index]) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
var url = window.location.pathname;
|
||||||
|
var currentParams = utils.params();
|
||||||
|
if (cids.length) {
|
||||||
|
currentParams.cid = cids;
|
||||||
|
url += '?' + decodeURIComponent($.param(currentParams));
|
||||||
|
}
|
||||||
|
ajaxify.go(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[component="category/list"]').on('click', '[data-cid]', function (ev) {
|
||||||
|
function selectChildren(parentCid, flag) {
|
||||||
|
$('[component="category/list"] [data-parent-cid="' + parentCid + '"] [component="category/select/icon"]').toggleClass('fa-check', flag);
|
||||||
|
$('[component="category/list"] [data-parent-cid="' + parentCid + '"]').each(function (index, el) {
|
||||||
|
selectChildren($(el).attr('data-cid'), flag);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var categoryEl = $(this);
|
||||||
|
var cid = $(this).attr('data-cid');
|
||||||
|
if (ev.ctrlKey) {
|
||||||
|
selectChildren(cid, !categoryEl.find('[component="category/select/icon"]').hasClass('fa-check'));
|
||||||
|
}
|
||||||
|
categoryEl.find('[component="category/select/icon"]').toggleClass('fa-check');
|
||||||
|
$('[component="category/list"] li').first().find('i').toggleClass('fa-check', !getSelectedCids().length);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
TopicList.loadMoreTopics = function (direction) {
|
||||||
|
if (!$('[component="category"]').length || !$('[component="category"]').children().length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var topics = $('[component="category/topic"]');
|
||||||
|
var afterEl = direction > 0 ? topics.last() : topics.first();
|
||||||
|
var after = (parseInt(afterEl.attr('data-index'), 10) || 0) + (direction > 0 ? 1 : 0);
|
||||||
|
|
||||||
|
if (!utils.isNumber(after) || (after === 0 && $('[component="category/topic"][data-index="0"]').length)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadFn = loadTopicsCallback || loadTopicsAfter;
|
||||||
|
loadFn(after, direction, function (data, done) {
|
||||||
|
if (data.topics && data.topics.length) {
|
||||||
|
TopicList.onTopicsLoaded(templateName, data.topics, data.privileges && data.privileges.editable, direction, done);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
$('#load-more-btn').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadTopicsAfter(after, direction, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
var query = utils.params();
|
||||||
|
infinitescroll.loadMore('topics.loadMoreSortedTopics', {
|
||||||
|
after: after,
|
||||||
|
direction: direction,
|
||||||
|
sort: tplToSort[templateName],
|
||||||
|
count: config.topicsPerPage,
|
||||||
|
cid: query.cid,
|
||||||
|
query: query,
|
||||||
|
term: ajaxify.data.selectedTerm.term,
|
||||||
|
filter: ajaxify.data.selectedFilter.filter,
|
||||||
|
set: $('[component="category"]').attr('data-set') ? $('[component="category"]').attr('data-set') : 'topics:recent',
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicList.onTopicsLoaded = function (templateName, topics, showSelect, direction, callback) {
|
||||||
|
topics = topics.filter(function (topic) {
|
||||||
|
return !$('[component="category/topic"][data-tid="' + topic.tid + '"]').length;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!topics.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
var after;
|
||||||
|
var before;
|
||||||
|
var topicsList = $('[component="category/topic"]');
|
||||||
|
|
||||||
|
if (direction > 0 && topics.length) {
|
||||||
|
after = topicsList.last();
|
||||||
|
} else if (direction < 0 && topics.length) {
|
||||||
|
before = topicsList.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
var tplData = {
|
||||||
|
topics: topics,
|
||||||
|
showSelect: showSelect,
|
||||||
|
template: {
|
||||||
|
name: templateName,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
tplData.template[templateName] = true;
|
||||||
|
|
||||||
|
app.parseAndTranslate(templateName, 'topics', tplData, function (html) {
|
||||||
|
$('[component="category"]').removeClass('hidden');
|
||||||
|
$('#category-no-topics').remove();
|
||||||
|
|
||||||
|
if (after && after.length) {
|
||||||
|
html.insertAfter(after);
|
||||||
|
} else if (before && before.length) {
|
||||||
|
var height = $(document).height();
|
||||||
|
var scrollTop = $(window).scrollTop();
|
||||||
|
|
||||||
|
html.insertBefore(before);
|
||||||
|
|
||||||
|
$(window).scrollTop(scrollTop + ($(document).height() - height));
|
||||||
|
} else {
|
||||||
|
$('[component="category"]').append(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!topicSelect.getSelectedTids().length) {
|
||||||
|
infinitescroll.removeExtra($('[component="category/topic"]'), direction, config.topicsPerPage * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.find('.timeago').timeago();
|
||||||
|
app.createUserTooltips();
|
||||||
|
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
||||||
|
$(window).trigger('action:topics.loaded', { topics: topics, template: templateName });
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return TopicList;
|
||||||
|
});
|
||||||
@@ -22,16 +22,13 @@ module.exports = function (Categories) {
|
|||||||
topics.getTopicsByTids(tids, data.uid, next);
|
topics.getTopicsByTids(tids, data.uid, next);
|
||||||
},
|
},
|
||||||
async.apply(user.blocks.filter, data.uid),
|
async.apply(user.blocks.filter, data.uid),
|
||||||
function (topics, next) {
|
function (topicsData, next) {
|
||||||
if (!topics.length) {
|
if (!topicsData.length) {
|
||||||
return next(null, { topics: [], uid: data.uid });
|
return next(null, { topics: [], uid: data.uid });
|
||||||
}
|
}
|
||||||
|
topics.calculateTopicIndices(topicsData, data.start);
|
||||||
|
|
||||||
for (var i = 0; i < topics.length; i += 1) {
|
plugins.fireHook('filter:category.topics.get', { cid: data.cid, topics: topicsData, uid: data.uid }, next);
|
||||||
topics[i].index = data.start + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins.fireHook('filter:category.topics.get', { cid: data.cid, topics: topics, uid: data.uid }, next);
|
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
next(null, { topics: results.topics, nextStart: data.stop + 1 });
|
next(null, { topics: results.topics, nextStart: data.stop + 1 });
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ exports.handleErrors = function (err, req, res, next) { // eslint-disable-line n
|
|||||||
return res.locals.isAPI ? res.set('X-Redirect', err.path).status(200).json(err.path) : res.redirect(err.path);
|
return res.locals.isAPI ? res.set('X-Redirect', err.path).status(200).json(err.path) : res.redirect(err.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
winston.error(req.path + '\n', err.stack);
|
winston.error(req.path + '\n', err);
|
||||||
|
|
||||||
res.status(status || 500);
|
res.status(status || 500);
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ recentController.getData = function (req, url, sort, callback) {
|
|||||||
data.allCategoriesUrl = url + helpers.buildQueryString('', filter, '');
|
data.allCategoriesUrl = url + helpers.buildQueryString('', filter, '');
|
||||||
data.selectedCategory = categoryData.selectedCategory;
|
data.selectedCategory = categoryData.selectedCategory;
|
||||||
data.selectedCids = categoryData.selectedCids;
|
data.selectedCids = categoryData.selectedCids;
|
||||||
data.nextStart = stop + 1;
|
|
||||||
data['feeds:disableRSS'] = meta.config['feeds:disableRSS'];
|
data['feeds:disableRSS'] = meta.config['feeds:disableRSS'];
|
||||||
data.rssFeedUrl = nconf.get('relative_path') + '/' + url + '.rss';
|
data.rssFeedUrl = nconf.get('relative_path') + '/' + url + '.rss';
|
||||||
if (req.loggedIn) {
|
if (req.loggedIn) {
|
||||||
|
|||||||
@@ -23,15 +23,16 @@ tagsController.getTag = function (req, res, next) {
|
|||||||
};
|
};
|
||||||
var settings;
|
var settings;
|
||||||
var topicCount = 0;
|
var topicCount = 0;
|
||||||
|
var start;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
user.getSettings(req.uid, next);
|
user.getSettings(req.uid, next);
|
||||||
},
|
},
|
||||||
function (_settings, next) {
|
function (_settings, next) {
|
||||||
settings = _settings;
|
settings = _settings;
|
||||||
var start = Math.max(0, (page - 1) * settings.topicsPerPage);
|
start = Math.max(0, (page - 1) * settings.topicsPerPage);
|
||||||
var stop = start + settings.topicsPerPage - 1;
|
var stop = start + settings.topicsPerPage - 1;
|
||||||
templateData.nextStart = stop + 1;
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
topicCount: function (next) {
|
topicCount: function (next) {
|
||||||
topics.getTagTopicCount(req.params.tag, next);
|
topics.getTagTopicCount(req.params.tag, next);
|
||||||
@@ -48,7 +49,8 @@ tagsController.getTag = function (req, res, next) {
|
|||||||
topicCount = results.topicCount;
|
topicCount = results.topicCount;
|
||||||
topics.getTopics(results.tids, req.uid, next);
|
topics.getTopics(results.tids, req.uid, next);
|
||||||
},
|
},
|
||||||
function (topics) {
|
function (topicsData) {
|
||||||
|
topics.calculateTopicIndices(topicsData, start);
|
||||||
res.locals.metaTags = [
|
res.locals.metaTags = [
|
||||||
{
|
{
|
||||||
name: 'title',
|
name: 'title',
|
||||||
@@ -59,7 +61,7 @@ tagsController.getTag = function (req, res, next) {
|
|||||||
content: tag,
|
content: tag,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
templateData.topics = topics;
|
templateData.topics = topicsData;
|
||||||
|
|
||||||
var pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
|
var pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
|
||||||
templateData.pagination = pagination.create(page, pageCount);
|
templateData.pagination = pagination.create(page, pageCount);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ mongoModule.getConnectionOptions = function () {
|
|||||||
reconnectTries: 3600,
|
reconnectTries: 3600,
|
||||||
reconnectInterval: 1000,
|
reconnectInterval: 1000,
|
||||||
autoReconnect: true,
|
autoReconnect: true,
|
||||||
connectTimeoutMS: 60000,
|
connectTimeoutMS: 90000,
|
||||||
useNewUrlParser: true,
|
useNewUrlParser: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ JS.scripts = {
|
|||||||
'public/src/modules/sort.js',
|
'public/src/modules/sort.js',
|
||||||
'public/src/modules/navigator.js',
|
'public/src/modules/navigator.js',
|
||||||
'public/src/modules/topicSelect.js',
|
'public/src/modules/topicSelect.js',
|
||||||
|
'public/src/modules/topicList.js',
|
||||||
'public/src/modules/categorySelector.js',
|
'public/src/modules/categorySelector.js',
|
||||||
'public/src/modules/share.js',
|
'public/src/modules/share.js',
|
||||||
'public/src/modules/search.js',
|
'public/src/modules/search.js',
|
||||||
|
|||||||
@@ -87,59 +87,43 @@ module.exports = function (SocketTopics) {
|
|||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketTopics.loadMoreUnreadTopics = function (socket, data, callback) {
|
SocketTopics.loadMoreSortedTopics = function (socket, data, callback) {
|
||||||
loadData(socket.uid, data, 'unread', callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketTopics.loadMoreRecentTopics = function (socket, data, callback) {
|
|
||||||
loadData(socket.uid, data, 'recent', callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketTopics.loadMorePopularTopics = function (socket, data, callback) {
|
|
||||||
loadData(socket.uid, data, 'posts', callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketTopics.loadMoreTopTopics = function (socket, data, callback) {
|
|
||||||
loadData(socket.uid, data, 'votes', callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadData(uid, data, sort, callback) {
|
|
||||||
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
|
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
}
|
}
|
||||||
|
const { start, stop } = calculateStartStop(data);
|
||||||
|
const params = {
|
||||||
|
uid: socket.uid,
|
||||||
|
start: start,
|
||||||
|
stop: stop,
|
||||||
|
filter: data.filter,
|
||||||
|
query: data.query,
|
||||||
|
};
|
||||||
|
if (data.sort === 'unread') {
|
||||||
|
params.cid = data.cid;
|
||||||
|
return topics.getUnreadTopics(params, callback);
|
||||||
|
}
|
||||||
|
params.cids = data.cid;
|
||||||
|
params.sort = data.sort;
|
||||||
|
params.term = data.term;
|
||||||
|
topics.getSortedTopics(params, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
SocketTopics.loadMoreFromSet = function (socket, data, callback) {
|
||||||
|
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
const { start, stop } = calculateStartStop(data);
|
||||||
|
topics.getTopicsFromSet(data.set, socket.uid, start, stop, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function calculateStartStop(data) {
|
||||||
var itemsPerPage = Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20);
|
var itemsPerPage = Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20);
|
||||||
var start = Math.max(0, parseInt(data.after, 10));
|
var start = Math.max(0, parseInt(data.after, 10));
|
||||||
if (data.direction === -1) {
|
if (data.direction === -1) {
|
||||||
start -= itemsPerPage;
|
start -= itemsPerPage;
|
||||||
}
|
}
|
||||||
var stop = start + Math.max(0, itemsPerPage - 1);
|
var stop = start + Math.max(0, itemsPerPage - 1);
|
||||||
start = Math.max(0, start);
|
return { start: Math.max(0, start), stop: Math.max(0, stop) };
|
||||||
stop = Math.max(0, stop);
|
|
||||||
const params = {
|
|
||||||
uid: uid,
|
|
||||||
start: start,
|
|
||||||
stop: stop,
|
|
||||||
filter: data.filter,
|
|
||||||
query: data.query,
|
|
||||||
};
|
|
||||||
if (sort === 'unread') {
|
|
||||||
params.cid = data.cid;
|
|
||||||
return topics.getUnreadTopics(params, callback);
|
|
||||||
}
|
}
|
||||||
params.cids = data.cid;
|
|
||||||
params.sort = sort;
|
|
||||||
params.term = data.term;
|
|
||||||
topics.getSortedTopics(params, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketTopics.loadMoreFromSet = function (socket, data, callback) {
|
|
||||||
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) {
|
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var start = parseInt(data.after, 10);
|
|
||||||
var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1);
|
|
||||||
|
|
||||||
topics.getTopicsFromSet(data.set, socket.uid, start, stop, callback);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ Topics.getTopicsFromSet = function (set, uid, start, stop, callback) {
|
|||||||
Topics.getTopics(tids, uid, next);
|
Topics.getTopics(tids, uid, next);
|
||||||
},
|
},
|
||||||
function (topics, next) {
|
function (topics, next) {
|
||||||
|
Topics.calculateTopicIndices(topics, start);
|
||||||
next(null, { topics: topics, nextStart: stop + 1 });
|
next(null, { topics: topics, nextStart: stop + 1 });
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
@@ -237,7 +238,7 @@ function getMainPostAndReplies(topic, set, uid, start, stop, reverse, callback)
|
|||||||
replies = posts.slice(1);
|
replies = posts.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Topics.calculatePostIndices(replies, start, stop, topic.postcount, reverse);
|
Topics.calculatePostIndices(replies, start, topic.postcount, reverse);
|
||||||
|
|
||||||
Topics.addPostData(posts, uid, next);
|
Topics.addPostData(posts, uid, next);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ module.exports = function (Topics) {
|
|||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
Topics.calculatePostIndices(results.posts, start, stop, results.postCount, reverse);
|
Topics.calculatePostIndices(results.posts, start, results.postCount, reverse);
|
||||||
|
|
||||||
Topics.addPostData(results.posts, uid, next);
|
Topics.addPostData(results.posts, uid, next);
|
||||||
},
|
},
|
||||||
@@ -183,7 +183,7 @@ module.exports = function (Topics) {
|
|||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Topics.calculatePostIndices = function (posts, start, stop, postCount, reverse) {
|
Topics.calculatePostIndices = function (posts, start, postCount, reverse) {
|
||||||
posts.forEach(function (post, index) {
|
posts.forEach(function (post, index) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
post.index = postCount - (start + index + 1);
|
post.index = postCount - (start + index + 1);
|
||||||
|
|||||||
@@ -178,11 +178,17 @@ module.exports = function (Topics) {
|
|||||||
Topics.getTopicsByTids(tids, params.uid, next);
|
Topics.getTopicsByTids(tids, params.uid, next);
|
||||||
},
|
},
|
||||||
function (topicData, next) {
|
function (topicData, next) {
|
||||||
topicData.forEach(function (topicObj, i) {
|
Topics.calculateTopicIndices(topicData, params.start);
|
||||||
topicObj.index = params.start + i;
|
|
||||||
});
|
|
||||||
next(null, topicData);
|
next(null, topicData);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Topics.calculateTopicIndices = function (topicData, start) {
|
||||||
|
topicData.forEach((topic, index) => {
|
||||||
|
if (topic) {
|
||||||
|
topic.index = start + index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -468,6 +468,7 @@ describe('socket.io', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should toggle plugin install', function (done) {
|
it('should toggle plugin install', function (done) {
|
||||||
|
this.timeout(0);
|
||||||
socketAdmin.plugins.toggleInstall({ uid: adminUid }, { id: 'nodebb-plugin-location-to-map', version: 'latest' }, function (err, data) {
|
socketAdmin.plugins.toggleInstall({ uid: adminUid }, { id: 'nodebb-plugin-location-to-map', version: 'latest' }, function (err, data) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(data.name, 'nodebb-plugin-location-to-map');
|
assert.equal(data.name, 'nodebb-plugin-location-to-map');
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ describe('Topic\'s', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error with invalid data', function (done) {
|
it('should error with invalid data', function (done) {
|
||||||
socketTopics.loadMoreUnreadTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
|
socketTopics.loadMoreSortedTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
|
||||||
assert.equal(err.message, '[[error:invalid-data]]');
|
assert.equal(err.message, '[[error:invalid-data]]');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -1073,7 +1073,7 @@ describe('Topic\'s', function () {
|
|||||||
it('should load more unread topics', function (done) {
|
it('should load more unread topics', function (done) {
|
||||||
socketTopics.markUnread({ uid: adminUid }, tid, function (err) {
|
socketTopics.markUnread({ uid: adminUid }, tid, function (err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
socketTopics.loadMoreUnreadTopics({ uid: adminUid }, { cid: topic.categoryId, after: 0, count: 10 }, function (err, data) {
|
socketTopics.loadMoreSortedTopics({ uid: adminUid }, { cid: topic.categoryId, after: 0, count: 10, sort: 'unread' }, function (err, data) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert(data);
|
assert(data);
|
||||||
assert(Array.isArray(data.topics));
|
assert(Array.isArray(data.topics));
|
||||||
@@ -1083,7 +1083,7 @@ describe('Topic\'s', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error with invalid data', function (done) {
|
it('should error with invalid data', function (done) {
|
||||||
socketTopics.loadMoreRecentTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
|
socketTopics.loadMoreSortedTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
|
||||||
assert.equal(err.message, '[[error:invalid-data]]');
|
assert.equal(err.message, '[[error:invalid-data]]');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -1091,7 +1091,7 @@ describe('Topic\'s', function () {
|
|||||||
|
|
||||||
|
|
||||||
it('should load more recent topics', function (done) {
|
it('should load more recent topics', function (done) {
|
||||||
socketTopics.loadMoreRecentTopics({ uid: adminUid }, { cid: topic.categoryId, after: 0, count: 10 }, function (err, data) {
|
socketTopics.loadMoreSortedTopics({ uid: adminUid }, { cid: topic.categoryId, after: 0, count: 10, sort: 'recent' }, function (err, data) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert(data);
|
assert(data);
|
||||||
assert(Array.isArray(data.topics));
|
assert(Array.isArray(data.topics));
|
||||||
|
|||||||
Reference in New Issue
Block a user