mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-05 03:51:26 +01:00
closes #6511
This commit is contained in:
@@ -11,9 +11,8 @@ define('forum/category', [
|
||||
'components',
|
||||
'translator',
|
||||
'topicSelect',
|
||||
'forum/pagination',
|
||||
'storage',
|
||||
], function (infinitescroll, share, navigator, categoryTools, recent, sort, components, translator, topicSelect, pagination, storage) {
|
||||
'handleBack',
|
||||
], function (infinitescroll, share, navigator, categoryTools, recent, sort, components, translator, topicSelect, handleBack) {
|
||||
var Category = {};
|
||||
|
||||
$(window).on('action:ajaxify.start', function (ev, data) {
|
||||
@@ -43,15 +42,8 @@ define('forum/category', [
|
||||
|
||||
enableInfiniteLoadingOrPagination();
|
||||
|
||||
$('[component="category"]').on('click', '[component="topic/header"]', function () {
|
||||
var clickedIndex = $(this).parents('[data-index]').attr('data-index');
|
||||
$('[component="category/topic"]').each(function (index, el) {
|
||||
if ($(el).offset().top - $(window).scrollTop() > 0) {
|
||||
storage.setItem('category:' + cid + ':bookmark', $(el).attr('data-index'));
|
||||
storage.setItem('category:' + cid + ':bookmark:clicked', clickedIndex);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
handleBack.init(function (after, cb) {
|
||||
loadTopicsAfter(after, 1, cb);
|
||||
});
|
||||
|
||||
handleScrollToTopicIndex();
|
||||
@@ -112,78 +104,6 @@ define('forum/category', [
|
||||
return bottomIndex;
|
||||
};
|
||||
|
||||
$(window).on('action:popstate', function () {
|
||||
if (ajaxify.data.template.category && ajaxify.data.cid) {
|
||||
var bookmarkIndex = storage.getItem('category:' + ajaxify.data.cid + ':bookmark');
|
||||
var clickedIndex = storage.getItem('category:' + ajaxify.data.cid + ':bookmark:clicked');
|
||||
|
||||
storage.removeItem('category:' + ajaxify.data.cid + ':bookmark');
|
||||
storage.removeItem('category:' + ajaxify.data.cid + ':bookmark:clicked');
|
||||
|
||||
bookmarkIndex = Math.max(0, parseInt(bookmarkIndex, 10) || 0);
|
||||
clickedIndex = Math.max(0, parseInt(clickedIndex, 10) || 0);
|
||||
if (!parseInt(bookmarkIndex, 10)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.usePagination) {
|
||||
var page = Math.ceil((parseInt(bookmarkIndex, 10) + 1) / config.topicsPerPage);
|
||||
if (parseInt(page, 10) !== ajaxify.data.pagination.currentPage) {
|
||||
pagination.loadPage(page, function () {
|
||||
Category.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
});
|
||||
} else {
|
||||
Category.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
}
|
||||
} else {
|
||||
if (bookmarkIndex === 0) {
|
||||
Category.highlightTopic(clickedIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
$('[component="category"]').empty();
|
||||
|
||||
loadTopicsAfter(Math.max(0, bookmarkIndex - 1) + 1, 1, function () {
|
||||
$(window).one('action:topics.loaded', function () {
|
||||
Category.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Category.highlightTopic = function (topicIndex) {
|
||||
var highlight = components.get('category/topic', 'index', topicIndex);
|
||||
|
||||
if (highlight.length && !highlight.hasClass('highlight')) {
|
||||
highlight.addClass('highlight');
|
||||
setTimeout(function () {
|
||||
highlight.removeClass('highlight');
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
Category.scrollToTopic = function (bookmarkIndex, clickedIndex, duration, offset) {
|
||||
if (!bookmarkIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offset) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var scrollTo = components.get('category/topic', 'index', bookmarkIndex);
|
||||
|
||||
if (scrollTo.length) {
|
||||
$('html, body').animate({
|
||||
scrollTop: (scrollTo.offset().top - offset) + 'px',
|
||||
}, duration !== undefined ? duration : 400, function () {
|
||||
Category.highlightTopic(clickedIndex);
|
||||
navigator.update();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function enableInfiniteLoadingOrPagination() {
|
||||
if (!config.usePagination) {
|
||||
navigator.init('[component="category/topic"]', ajaxify.data.topic_count, Category.toTop, Category.toBottom, Category.navigatorCallback);
|
||||
|
||||
@@ -28,7 +28,7 @@ define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'],
|
||||
term: ajaxify.data.term,
|
||||
}, function (data, done) {
|
||||
if (data.topics && data.topics.length) {
|
||||
recent.onTopicsLoaded('popular', data.topics, false, done);
|
||||
recent.onTopicsLoaded('popular', data.topics, false, direction, done);
|
||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
done();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
define('forum/recent', ['forum/infinitescroll', 'components'], function (infinitescroll, components) {
|
||||
define('forum/recent', ['forum/infinitescroll', 'components', 'handleBack'], function (infinitescroll, components, handleBack) {
|
||||
var Recent = {};
|
||||
|
||||
var newTopicCount = 0;
|
||||
@@ -20,6 +19,10 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
|
||||
|
||||
Recent.handleCategorySelection();
|
||||
|
||||
handleBack.init(function (after, cb) {
|
||||
loadTopicsAfter(after, 1, cb);
|
||||
});
|
||||
|
||||
$('#new-topics-alert').on('click', function () {
|
||||
$(this).addClass('hide');
|
||||
});
|
||||
@@ -186,27 +189,36 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
|
||||
};
|
||||
|
||||
Recent.loadMoreTopics = function (direction) {
|
||||
if (direction < 0 || !$('[component="category"]').length) {
|
||||
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 () {};
|
||||
infinitescroll.loadMore('topics.loadMoreRecentTopics', {
|
||||
after: $('[component="category"]').attr('data-nextstart'),
|
||||
after: after,
|
||||
direction: direction,
|
||||
count: config.topicsPerPage,
|
||||
cid: utils.params().cid,
|
||||
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, done);
|
||||
Recent.onTopicsLoaded('recent', data.topics, false, direction, done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
||||
callback();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Recent.onTopicsLoaded = function (templateName, topics, showSelect, callback) {
|
||||
Recent.onTopicsLoaded = function (templateName, topics, showSelect, direction, callback) {
|
||||
topics = topics.filter(function (topic) {
|
||||
return !components.get('category/topic', 'tid', topic.tid).length;
|
||||
});
|
||||
@@ -215,10 +227,32 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
|
||||
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();
|
||||
|
||||
html.insertAfter($('[component="category/topic"]').last());
|
||||
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'));
|
||||
|
||||
@@ -30,7 +30,7 @@ define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent,
|
||||
count: config.topicsPerPage,
|
||||
}, function (data, done) {
|
||||
if (data.topics && data.topics.length) {
|
||||
recent.onTopicsLoaded('tag', data.topics, false, done);
|
||||
recent.onTopicsLoaded('tag', data.topics, false, direction, done);
|
||||
} else {
|
||||
done();
|
||||
$('#load-more-btn').hide();
|
||||
|
||||
@@ -39,7 +39,7 @@ define('forum/top', ['forum/recent', 'forum/infinitescroll'], function (recent,
|
||||
filter: ajaxify.data.selectedFilter.filter,
|
||||
}, function (data, done) {
|
||||
if (data.topics && data.topics.length) {
|
||||
recent.onTopicsLoaded('top', data.topics, true, done);
|
||||
recent.onTopicsLoaded('top', data.topics, true, direction, done);
|
||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
done();
|
||||
|
||||
@@ -98,7 +98,7 @@ define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', '
|
||||
filter: ajaxify.data.selectedFilter.filter,
|
||||
}, function (data, done) {
|
||||
if (data.topics && data.topics.length) {
|
||||
recent.onTopicsLoaded('unread', data.topics, true, done);
|
||||
recent.onTopicsLoaded('unread', data.topics, true, direction, done);
|
||||
$('[component="category"]').attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
done();
|
||||
|
||||
103
public/src/modules/handleBack.js
Normal file
103
public/src/modules/handleBack.js
Normal file
@@ -0,0 +1,103 @@
|
||||
'use strict';
|
||||
|
||||
define('handleBack', [
|
||||
'components',
|
||||
'storage',
|
||||
'navigator',
|
||||
'forum/pagination',
|
||||
], function (components, storage, navigator, pagination) {
|
||||
var handleBack = {};
|
||||
var loadTopicsMethod;
|
||||
|
||||
handleBack.init = function (_loadTopicsMethod) {
|
||||
loadTopicsMethod = _loadTopicsMethod;
|
||||
saveClickedIndex();
|
||||
$(window).off('action:popstate', onBackClicked).on('action:popstate', onBackClicked);
|
||||
};
|
||||
|
||||
function saveClickedIndex() {
|
||||
$('[component="category"]').on('click', '[component="topic/header"]', function () {
|
||||
var clickedIndex = $(this).parents('[data-index]').attr('data-index');
|
||||
$('[component="category/topic"]').each(function (index, el) {
|
||||
if ($(el).offset().top - $(window).scrollTop() > 0) {
|
||||
storage.setItem('category:bookmark', $(el).attr('data-index'));
|
||||
storage.setItem('category:bookmark:clicked', clickedIndex);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onBackClicked() {
|
||||
if ((ajaxify.data.template.category || ajaxify.data.template.recent)) {
|
||||
var bookmarkIndex = storage.getItem('category:bookmark');
|
||||
var clickedIndex = storage.getItem('category:bookmark:clicked');
|
||||
|
||||
storage.removeItem('category:bookmark');
|
||||
storage.removeItem('category:bookmark:clicked');
|
||||
|
||||
bookmarkIndex = Math.max(0, parseInt(bookmarkIndex, 10) || 0);
|
||||
clickedIndex = Math.max(0, parseInt(clickedIndex, 10) || 0);
|
||||
if (!utils.isNumber(bookmarkIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.usePagination) {
|
||||
var page = Math.ceil((parseInt(bookmarkIndex, 10) + 1) / config.topicsPerPage);
|
||||
if (parseInt(page, 10) !== ajaxify.data.pagination.currentPage) {
|
||||
pagination.loadPage(page, function () {
|
||||
handleBack.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
});
|
||||
} else {
|
||||
handleBack.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
}
|
||||
} else {
|
||||
if (bookmarkIndex === 0) {
|
||||
handleBack.highlightTopic(clickedIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
$('[component="category"]').empty();
|
||||
loadTopicsMethod(Math.max(0, bookmarkIndex - 1) + 1, function () {
|
||||
$(window).one('action:topics.loaded', function () {
|
||||
handleBack.scrollToTopic(bookmarkIndex, clickedIndex, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleBack.highlightTopic = function (topicIndex) {
|
||||
var highlight = components.get('category/topic', 'index', topicIndex);
|
||||
|
||||
if (highlight.length && !highlight.hasClass('highlight')) {
|
||||
highlight.addClass('highlight');
|
||||
setTimeout(function () {
|
||||
highlight.removeClass('highlight');
|
||||
}, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
handleBack.scrollToTopic = function (bookmarkIndex, clickedIndex, duration, offset) {
|
||||
if (!utils.isNumber(bookmarkIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offset) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var scrollTo = components.get('category/topic', 'index', bookmarkIndex);
|
||||
|
||||
if (scrollTo.length) {
|
||||
$('html, body').animate({
|
||||
scrollTop: (scrollTo.offset().top - offset) + 'px',
|
||||
}, duration !== undefined ? duration : 400, function () {
|
||||
handleBack.highlightTopic(clickedIndex);
|
||||
navigator.update();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return handleBack;
|
||||
});
|
||||
@@ -75,6 +75,7 @@ JS.scripts = {
|
||||
'public/src/modules/helpers.js',
|
||||
'public/src/modules/flags.js',
|
||||
'public/src/modules/storage.js',
|
||||
'public/src/modules/handleBack.js',
|
||||
],
|
||||
|
||||
admin: [
|
||||
|
||||
@@ -115,8 +115,14 @@ module.exports = function (SocketTopics) {
|
||||
if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
|
||||
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);
|
||||
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);
|
||||
loadFn(start, stop);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ module.exports = function (Topics) {
|
||||
Topics.getTopicsByTids(tids, uid, next);
|
||||
},
|
||||
function (topicData, next) {
|
||||
topicData.forEach(function (topicObj, i) {
|
||||
topicObj.index = start + i;
|
||||
});
|
||||
recentTopics.topics = topicData;
|
||||
recentTopics.nextStart = stop + 1;
|
||||
next(null, recentTopics);
|
||||
|
||||
Reference in New Issue
Block a user