mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-01-01 13:20:41 +01:00
feat: ability to go through your posts in a topic
because I am 👴 useful for large topics
This commit is contained in:
@@ -95,7 +95,7 @@
|
||||
"nodebb-plugin-spam-be-gone": "0.7.13",
|
||||
"nodebb-rewards-essentials": "0.2.1",
|
||||
"nodebb-theme-lavender": "5.3.2",
|
||||
"nodebb-theme-persona": "11.3.38",
|
||||
"nodebb-theme-persona": "11.3.39",
|
||||
"nodebb-theme-slick": "1.4.23",
|
||||
"nodebb-theme-vanilla": "12.1.17",
|
||||
"nodebb-widget-essentials": "5.0.9",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
"pagination": "Pagination",
|
||||
"pagination.out_of": "%1 out of %2",
|
||||
"pagination.enter_index": "Enter index",
|
||||
"pagination.enter_index": "Go to post index",
|
||||
|
||||
"header.admin": "Admin",
|
||||
"header.categories": "Categories",
|
||||
|
||||
@@ -207,5 +207,7 @@
|
||||
"timeago_earlier": "%1 earlier",
|
||||
"first-post": "First post",
|
||||
"last-post": "Last post",
|
||||
"go-to-my-next-post": "Go to my next post",
|
||||
"no-more-next-post": "You don't have any other posts in this topic",
|
||||
"post-quick-reply": "Post quick reply"
|
||||
}
|
||||
|
||||
@@ -54,15 +54,20 @@ define('navigator', ['forum/pagination', 'components', 'hooks', 'alerts'], funct
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
paginationBlockEl.off('shown.bs.dropdown', '.dropdown').on('shown.bs.dropdown', '.dropdown', function () {
|
||||
setTimeout(function () {
|
||||
paginationBlockEl.off('shown.bs.dropdown', '.wrapper').on('shown.bs.dropdown', '.wrapper', function () {
|
||||
setTimeout(async function () {
|
||||
$('.pagination-block input').focus();
|
||||
const postCountInTopic = await socket.emit('topics.getPostCountInTopic', ajaxify.data.tid);
|
||||
if (postCountInTopic > 0) {
|
||||
paginationBlockEl.find('#myNextPostBtn').removeAttr('disabled');
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
paginationBlockEl.find('.pageup').off('click').on('click', navigator.scrollUp);
|
||||
paginationBlockEl.find('.pagedown').off('click').on('click', navigator.scrollDown);
|
||||
paginationBlockEl.find('.pagetop').off('click').on('click', navigator.toTop);
|
||||
paginationBlockEl.find('.pagebottom').off('click').on('click', navigator.toBottom);
|
||||
paginationBlockEl.find('#myNextPostBtn').off('click').on('click', gotoMyNextPost);
|
||||
|
||||
paginationBlockEl.find('input').on('keydown', function (e) {
|
||||
if (e.which === 13) {
|
||||
@@ -90,6 +95,40 @@ define('navigator', ['forum/pagination', 'components', 'hooks', 'alerts'], funct
|
||||
navigator.update(0);
|
||||
};
|
||||
|
||||
let lastNextIndex = 0;
|
||||
async function gotoMyNextPost() {
|
||||
async function getNext(startIndex) {
|
||||
return await socket.emit('topics.getMyNextPostIndex', {
|
||||
tid: ajaxify.data.tid,
|
||||
index: Math.max(1, startIndex),
|
||||
sort: config.topicPostSort,
|
||||
});
|
||||
}
|
||||
if (ajaxify.data.template.topic) {
|
||||
let nextIndex = await getNext(index);
|
||||
if (lastNextIndex === nextIndex) { // handles last post in pagination
|
||||
console.log('fail', nextIndex, lastNextIndex);
|
||||
nextIndex = await getNext(nextIndex);
|
||||
}
|
||||
if (nextIndex) {
|
||||
lastNextIndex = nextIndex;
|
||||
$(window).one('action:ajaxify.end', function () {
|
||||
if (paginationBlockEl.find('.dropdown-menu').is(':hidden')) {
|
||||
paginationBlockEl.find('.dropdown-toggle').dropdown('toggle');
|
||||
}
|
||||
});
|
||||
navigator.scrollToIndex(nextIndex, true, 0);
|
||||
} else {
|
||||
alerts.alert({
|
||||
message: '[[topic:no-more-next-post]]',
|
||||
type: 'info',
|
||||
});
|
||||
|
||||
lastNextIndex = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clampTop(newTop) {
|
||||
const parent = thumb.parent();
|
||||
const parentOffset = parent.offset();
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const db = require('../database');
|
||||
const posts = require('../posts');
|
||||
const topics = require('../topics');
|
||||
const user = require('../user');
|
||||
const meta = require('../meta');
|
||||
const privileges = require('../privileges');
|
||||
const cache = require('../cache');
|
||||
|
||||
const SocketTopics = module.exports;
|
||||
|
||||
@@ -54,4 +59,52 @@ SocketTopics.isModerator = async function (socket, tid) {
|
||||
return await user.isModerator(socket.uid, cid);
|
||||
};
|
||||
|
||||
SocketTopics.getMyNextPostIndex = async function (socket, data) {
|
||||
if (!data || !data.tid || !data.index || !data.sort) {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
}
|
||||
|
||||
async function getTopicPids(index) {
|
||||
const topicSet = data.sort === 'most_votes' ? `tid:${data.tid}:posts:votes` : `tid:${data.tid}:posts`;
|
||||
const reverse = data.sort === 'newest_to_oldest' || data.sort === 'most_votes';
|
||||
const cacheKey = `np:s:${topicSet}:r:${String(reverse)}:tid:${data.tid}:pids`;
|
||||
const topicPids = cache.get(cacheKey);
|
||||
if (topicPids) {
|
||||
return topicPids.slice(index - 1);
|
||||
}
|
||||
const pids = await db[reverse ? 'getSortedSetRevRange' : 'getSortedSetRange'](topicSet, 0, -1);
|
||||
cache.set(cacheKey, pids, 30000);
|
||||
return pids.slice(index - 1);
|
||||
}
|
||||
|
||||
async function getUserPids() {
|
||||
const cid = await topics.getTopicField(data.tid, 'cid');
|
||||
const cacheKey = `np:cid:${cid}:uid:${socket.uid}:pids`;
|
||||
const userPids = cache.get(cacheKey);
|
||||
if (userPids) {
|
||||
return userPids;
|
||||
}
|
||||
const pids = await db.getSortedSetRange(`cid:${cid}:uid:${socket.uid}:pids`, 0, -1);
|
||||
cache.set(cacheKey, pids, 30000);
|
||||
return pids;
|
||||
}
|
||||
|
||||
const [topicPids, userPidsInCategory] = await Promise.all([
|
||||
getTopicPids(data.index),
|
||||
getUserPids(),
|
||||
]);
|
||||
const userPidsInTopic = _.intersection(topicPids, userPidsInCategory);
|
||||
if (!userPidsInTopic.length) {
|
||||
return 0;
|
||||
}
|
||||
return await posts.getPidIndex(userPidsInTopic[0], data.tid, data.sort);
|
||||
};
|
||||
|
||||
SocketTopics.getPostCountInTopic = async function (socket, tid) {
|
||||
if (!socket.uid || !tid) {
|
||||
return 0;
|
||||
}
|
||||
return await db.sortedSetScore(`tid:${tid}:posters`, socket.uid);
|
||||
};
|
||||
|
||||
require('../promisify')(SocketTopics);
|
||||
|
||||
Reference in New Issue
Block a user