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
v1.18.x
Barış Soner Uşaklı 6 years ago committed by GitHub
parent aa301f27a1
commit c27be9db5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,18 +1,13 @@
'use strict';
define('forum/category', [
'forum/infinitescroll',
'share',
'navigator',
'forum/category/tools',
'forum/recent',
'topicList',
'sort',
'components',
'translator',
'topicSelect',
'handleBack',
], function (infinitescroll, share, navigator, categoryTools, recent, sort, components, translator, topicSelect, handleBack) {
], function (infinitescroll, share, navigator, categoryTools, topicList, sort) {
var Category = {};
$(window).on('action:ajaxify.start', function (ev, data) {
@ -25,7 +20,7 @@ define('forum/category', [
function removeListeners() {
categoryTools.removeListeners();
recent.removeListeners();
topicList.removeListeners();
}
Category.init = function () {
@ -36,15 +31,16 @@ define('forum/category', [
share.addShareHandlers(ajaxify.data.name);
categoryTools.init(cid);
recent.watchForNewPosts();
sort.handleSort('categoryTopicSort', 'user.setCategorySort', 'category/' + ajaxify.data.slug);
topicList.init('category', loadTopicsAfter);
enableInfiniteLoadingOrPagination();
sort.handleSort('categoryTopicSort', 'user.setCategorySort', 'category/' + ajaxify.data.slug);
handleBack.init(function (after, cb) {
loadTopicsAfter(after, 1, cb);
});
if (!config.usePagination) {
navigator.init('[component="category/topic"]', ajaxify.data.topic_count, Category.toTop, Category.toBottom, Category.navigatorCallback);
} else {
navigator.disable();
}
handleScrollToTopicIndex();
@ -104,32 +100,8 @@ define('forum/category', [
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) {
callback = callback || function () {};
if (!utils.isNumber(after) || (after === 0 && components.get('category/topic', 'index', 0).length)) {
return callback();
}
$(window).trigger('action:category.loading');
var params = utils.params();
@ -140,78 +112,10 @@ define('forum/category', [
query: params,
categoryTopicSort: config.categoryTopicSort,
}, function (data, done) {
if (data.topics && data.topics.length) {
Category.onTopicsLoaded(data, direction, done);
} else {
done();
}
$(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;
});

@ -16,7 +16,7 @@ define('forum/infinitescroll', function () {
callback = cb;
container = el || $('body');
}
previousScrollTop = $(window).scrollTop();
$(window).off('scroll', onScroll).on('scroll', onScroll);
};

@ -1,40 +1,14 @@
'use strict';
define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'], function (recent, components, infinitescroll) {
define('forum/popular', ['topicList'], function (topicList) {
var Popular = {};
Popular.init = function () {
app.enterRoom('popular_topics');
recent.handleCategorySelection();
if (!config.usePagination) {
infinitescroll.init(loadMoreTopics);
}
topicList.init('popular');
};
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;
});

@ -1,268 +1,12 @@
'use strict';
define('forum/recent', ['forum/infinitescroll', 'components', 'handleBack'], function (infinitescroll, components, handleBack) {
define('forum/recent', ['topicList'], function (topicList) {
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 () {
app.enterRoom('recent_topics');
Recent.watchForNewPosts();
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();
});
topicList.init('recent');
};
return Recent;

@ -1,42 +1,21 @@
'use strict';
define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) {
define('forum/tag', ['topicList', 'forum/infinitescroll'], function (topicList, infinitescroll) {
var Tag = {};
Tag.init = function () {
app.enterRoom('tags');
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;
}
topicList.init('tag', loadMoreTopics);
function loadMoreTopics(after, direction, callback) {
infinitescroll.loadMore('topics.loadMoreFromSet', {
set: 'tag:' + ajaxify.data.tag + ':topics',
after: $('[component="category"]').attr('data-nextstart'),
after: after,
direction: direction,
count: config.topicsPerPage,
}, function (data, done) {
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);
});
}, callback);
}
};

@ -1,54 +1,13 @@
'use strict';
define('forum/top', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) {
define('forum/top', ['topicList'], function (topicList) {
var Top = {};
$(window).on('action:ajaxify.start', function (ev, data) {
if (ajaxify.currentPage !== data.url) {
recent.removeListeners();
}
});
Top.init = function () {
app.enterRoom('top_topics');
recent.watchForNewPosts();
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 });
topicList.init('top');
};
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;
});

@ -1,27 +1,14 @@
'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 = {};
$(window).on('action:ajaxify.start', function (ev, data) {
if (ajaxify.currentPage !== data.url) {
recent.removeListeners();
}
});
Unread.init = function () {
app.enterRoom('unread_topics');
$('#new-topics-alert').on('click', function () {
$(this).addClass('hide');
});
recent.watchForNewPosts();
recent.handleCategorySelection();
$(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
topicList.init('unread');
topicSelect.init();
$('#markSelectedRead').on('click', function () {
var tids = topicSelect.getSelectedTids();
@ -71,42 +58,6 @@ define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', '
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) {

@ -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);
},
async.apply(user.blocks.filter, data.uid),
function (topics, next) {
if (!topics.length) {
function (topicsData, next) {
if (!topicsData.length) {
return next(null, { topics: [], uid: data.uid });
}
topics.calculateTopicIndices(topicsData, data.start);
for (var i = 0; i < topics.length; i += 1) {
topics[i].index = data.start + i;
}
plugins.fireHook('filter:category.topics.get', { cid: data.cid, topics: topics, uid: data.uid }, next);
plugins.fireHook('filter:category.topics.get', { cid: data.cid, topics: topicsData, uid: data.uid }, next);
},
function (results, next) {
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);
}
winston.error(req.path + '\n', err.stack);
winston.error(req.path + '\n', err);
res.status(status || 500);

@ -79,7 +79,6 @@ recentController.getData = function (req, url, sort, callback) {
data.allCategoriesUrl = url + helpers.buildQueryString('', filter, '');
data.selectedCategory = categoryData.selectedCategory;
data.selectedCids = categoryData.selectedCids;
data.nextStart = stop + 1;
data['feeds:disableRSS'] = meta.config['feeds:disableRSS'];
data.rssFeedUrl = nconf.get('relative_path') + '/' + url + '.rss';
if (req.loggedIn) {

@ -23,15 +23,16 @@ tagsController.getTag = function (req, res, next) {
};
var settings;
var topicCount = 0;
var start;
async.waterfall([
function (next) {
user.getSettings(req.uid, next);
},
function (_settings, next) {
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;
templateData.nextStart = stop + 1;
async.parallel({
topicCount: function (next) {
topics.getTagTopicCount(req.params.tag, next);
@ -48,7 +49,8 @@ tagsController.getTag = function (req, res, next) {
topicCount = results.topicCount;
topics.getTopics(results.tids, req.uid, next);
},
function (topics) {
function (topicsData) {
topics.calculateTopicIndices(topicsData, start);
res.locals.metaTags = [
{
name: 'title',
@ -59,7 +61,7 @@ tagsController.getTag = function (req, res, next) {
content: tag,
},
];
templateData.topics = topics;
templateData.topics = topicsData;
var pageCount = Math.max(1, Math.ceil(topicCount / settings.topicsPerPage));
templateData.pagination = pagination.create(page, pageCount);

@ -100,7 +100,7 @@ mongoModule.getConnectionOptions = function () {
reconnectTries: 3600,
reconnectInterval: 1000,
autoReconnect: true,
connectTimeoutMS: 60000,
connectTimeoutMS: 90000,
useNewUrlParser: true,
};

@ -67,6 +67,7 @@ JS.scripts = {
'public/src/modules/sort.js',
'public/src/modules/navigator.js',
'public/src/modules/topicSelect.js',
'public/src/modules/topicList.js',
'public/src/modules/categorySelector.js',
'public/src/modules/share.js',
'public/src/modules/search.js',

@ -87,59 +87,43 @@ module.exports = function (SocketTopics) {
], callback);
};
SocketTopics.loadMoreUnreadTopics = 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) {
SocketTopics.loadMoreSortedTopics = function (socket, data, callback) {
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback(new Error('[[error:invalid-data]]'));
}
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));
if (data.direction === -1) {
start -= itemsPerPage;
}
var stop = start + Math.max(0, itemsPerPage - 1);
start = Math.max(0, start);
stop = Math.max(0, stop);
const { start, stop } = calculateStartStop(data);
const params = {
uid: uid,
uid: socket.uid,
start: start,
stop: stop,
filter: data.filter,
query: data.query,
};
if (sort === 'unread') {
if (data.sort === 'unread') {
params.cid = data.cid;
return topics.getUnreadTopics(params, callback);
}
params.cids = data.cid;
params.sort = sort;
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]]'));
}
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);
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 start = Math.max(0, parseInt(data.after, 10));
if (data.direction === -1) {
start -= itemsPerPage;
}
var stop = start + Math.max(0, itemsPerPage - 1);
return { start: Math.max(0, start), stop: Math.max(0, stop) };
}
};

@ -46,6 +46,7 @@ Topics.getTopicsFromSet = function (set, uid, start, stop, callback) {
Topics.getTopics(tids, uid, next);
},
function (topics, next) {
Topics.calculateTopicIndices(topics, start);
next(null, { topics: topics, nextStart: stop + 1 });
},
], callback);
@ -237,7 +238,7 @@ function getMainPostAndReplies(topic, set, uid, start, stop, reverse, callback)
replies = posts.slice(1);
}
Topics.calculatePostIndices(replies, start, stop, topic.postcount, reverse);
Topics.calculatePostIndices(replies, start, topic.postcount, reverse);
Topics.addPostData(posts, uid, next);
},

@ -37,7 +37,7 @@ module.exports = function (Topics) {
}, 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);
},
@ -183,7 +183,7 @@ module.exports = function (Topics) {
], callback);
};
Topics.calculatePostIndices = function (posts, start, stop, postCount, reverse) {
Topics.calculatePostIndices = function (posts, start, postCount, reverse) {
posts.forEach(function (post, index) {
if (reverse) {
post.index = postCount - (start + index + 1);

@ -178,11 +178,17 @@ module.exports = function (Topics) {
Topics.getTopicsByTids(tids, params.uid, next);
},
function (topicData, next) {
topicData.forEach(function (topicObj, i) {
topicObj.index = params.start + i;
});
Topics.calculateTopicIndices(topicData, params.start);
next(null, topicData);
},
], 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) {
this.timeout(0);
socketAdmin.plugins.toggleInstall({ uid: adminUid }, { id: 'nodebb-plugin-location-to-map', version: 'latest' }, function (err, data) {
assert.ifError(err);
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) {
socketTopics.loadMoreUnreadTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
socketTopics.loadMoreSortedTopics({ uid: adminUid }, { after: 'invalid' }, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
@ -1073,7 +1073,7 @@ describe('Topic\'s', function () {
it('should load more unread topics', function (done) {
socketTopics.markUnread({ uid: adminUid }, tid, function (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(data);
assert(Array.isArray(data.topics));
@ -1083,7 +1083,7 @@ describe('Topic\'s', function () {
});
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]]');
done();
});
@ -1091,7 +1091,7 @@ describe('Topic\'s', function () {
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(data);
assert(Array.isArray(data.topics));

Loading…
Cancel
Save