mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
refactor: posts api
This commit is contained in:
@@ -8,15 +8,6 @@ define('forum/topic/votes', [
|
|||||||
|
|
||||||
Votes.addVoteHandler = function () {
|
Votes.addVoteHandler = function () {
|
||||||
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', loadDataAndCreateTooltip);
|
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', loadDataAndCreateTooltip);
|
||||||
components.get('topic').on('mouseout', '[data-pid] [component="post/vote-count"]', function () {
|
|
||||||
var el = $(this).parent();
|
|
||||||
el.on('shown.bs.tooltip', function () {
|
|
||||||
$('.tooltip').tooltip('destroy');
|
|
||||||
el.off('shown.bs.tooltip');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.tooltip').tooltip('destroy');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadDataAndCreateTooltip(e) {
|
function loadDataAndCreateTooltip(e) {
|
||||||
@@ -26,18 +17,14 @@ define('forum/topic/votes', [
|
|||||||
var el = $this.parent();
|
var el = $this.parent();
|
||||||
var pid = el.parents('[data-pid]').attr('data-pid');
|
var pid = el.parents('[data-pid]').attr('data-pid');
|
||||||
|
|
||||||
$('.tooltip').tooltip('destroy');
|
|
||||||
$this.off('mouseenter', loadDataAndCreateTooltip);
|
|
||||||
|
|
||||||
socket.emit('posts.getUpvoters', [pid], function (err, data) {
|
socket.emit('posts.getUpvoters', [pid], function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length) {
|
if (data.length) {
|
||||||
createTooltip(el, data[0]);
|
createTooltip($this, data[0]);
|
||||||
}
|
}
|
||||||
$this.off('mouseenter').on('mouseenter', loadDataAndCreateTooltip);
|
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -46,7 +33,8 @@ define('forum/topic/votes', [
|
|||||||
function doCreateTooltip(title) {
|
function doCreateTooltip(title) {
|
||||||
el.attr('title', title).tooltip('fixTitle').tooltip('show');
|
el.attr('title', title).tooltip('fixTitle').tooltip('show');
|
||||||
}
|
}
|
||||||
var usernames = data.usernames;
|
var usernames = data.usernames
|
||||||
|
.filter(name => name !== '[[global:former_user]]');
|
||||||
if (!usernames.length) {
|
if (!usernames.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -70,10 +58,10 @@ define('forum/topic/votes', [
|
|||||||
const method = currentState ? 'del' : 'put';
|
const method = currentState ? 'del' : 'put';
|
||||||
api[method](`/posts/${post.attr('data-pid')}/vote`, {
|
api[method](`/posts/${post.attr('data-pid')}/vote`, {
|
||||||
delta: delta,
|
delta: delta,
|
||||||
}, undefined, (err) => {
|
}).catch((err) => {
|
||||||
app.alertError(err.status.message);
|
app.alertError(err.message);
|
||||||
|
|
||||||
if (err.status.message === '[[error:not-logged-in]]') {
|
if (err.message === '[[error:not-logged-in]]') {
|
||||||
ajaxify.go('login');
|
ajaxify.go('login');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,13 +22,7 @@ define('api', () => {
|
|||||||
ev.responseJSON.status.message :
|
ev.responseJSON.status.message :
|
||||||
ev.responseJSON.error;
|
ev.responseJSON.error;
|
||||||
|
|
||||||
const error = new Error(errMessage || ev.statusText);
|
cb(new Error(errMessage || ev.statusText));
|
||||||
|
|
||||||
if (!utils.hasLanguageKey(error.message)) {
|
|
||||||
app.alertError(error.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(error);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
const url = require('url');
|
const url = require('url');
|
||||||
const user = require('../user');
|
const user = require('../user');
|
||||||
const topics = require('../topics');
|
const topics = require('../topics');
|
||||||
|
const posts = require('../posts');
|
||||||
const privileges = require('../privileges');
|
const privileges = require('../privileges');
|
||||||
|
const plugins = require('../plugins');
|
||||||
const socketHelpers = require('../socket.io/helpers');
|
const socketHelpers = require('../socket.io/helpers');
|
||||||
|
const websockets = require('../socket.io');
|
||||||
const events = require('../events');
|
const events = require('../events');
|
||||||
|
|
||||||
// creates a slimmed down version of the request object
|
// creates a slimmed down version of the request object
|
||||||
@@ -34,7 +37,6 @@ exports.buildReqObject = (req, payload) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.doTopicAction = async function (action, event, caller, { tids }) {
|
exports.doTopicAction = async function (action, event, caller, { tids }) {
|
||||||
if (!Array.isArray(tids)) {
|
if (!Array.isArray(tids)) {
|
||||||
throw new Error('[[error:invalid-tid]]');
|
throw new Error('[[error:invalid-tid]]');
|
||||||
@@ -73,3 +75,59 @@ async function logTopicAction(action, req, tid, title) {
|
|||||||
title: String(title),
|
title: String(title),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.postCommand = async function (caller, command, eventName, notification, data) {
|
||||||
|
if (!caller.uid) {
|
||||||
|
throw new Error('[[error:not-logged-in]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data || !data.pid) {
|
||||||
|
throw new Error('[[error:invalid-data]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.room_id) {
|
||||||
|
throw new Error('[[error:invalid-room-id, ' + data.room_id + ' ]]');
|
||||||
|
}
|
||||||
|
const [exists, deleted] = await Promise.all([
|
||||||
|
posts.exists(data.pid),
|
||||||
|
posts.getPostField(data.pid, 'deleted'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
throw new Error('[[error:invalid-pid]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleted) {
|
||||||
|
throw new Error('[[error:post-deleted]]');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
hooks:
|
||||||
|
filter:post.upvote
|
||||||
|
filter:post.downvote
|
||||||
|
filter:post.unvote
|
||||||
|
filter:post.bookmark
|
||||||
|
filter:post.unbookmark
|
||||||
|
*/
|
||||||
|
const filteredData = await plugins.fireHook('filter:post.' + command, {
|
||||||
|
data: data,
|
||||||
|
uid: caller.uid,
|
||||||
|
});
|
||||||
|
return await executeCommand(caller, command, eventName, notification, filteredData.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function executeCommand(caller, command, eventName, notification, data) {
|
||||||
|
const result = await posts[command](data.pid, caller.uid);
|
||||||
|
if (result && eventName) {
|
||||||
|
websockets.in('uid_' + caller.uid).emit('posts.' + command, result);
|
||||||
|
websockets.in(data.room_id).emit('event:' + eventName, result);
|
||||||
|
}
|
||||||
|
if (result && command === 'upvote') {
|
||||||
|
socketHelpers.upvote(result, notification);
|
||||||
|
} else if (result && notification) {
|
||||||
|
socketHelpers.sendNotificationToPostOwner(data.pid, caller.uid, command, notification);
|
||||||
|
} else if (result && command === 'unvote') {
|
||||||
|
socketHelpers.rescindUpvoteNotification(data.pid, caller.uid);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -165,3 +165,22 @@ async function isMainAndLastPost(pid) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postsAPI.upvote = async function (caller, data) {
|
||||||
|
return await apiHelpers.postCommand(caller, 'upvote', 'voted', 'notifications:upvoted_your_post_in', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
postsAPI.downvote = async function (caller, data) {
|
||||||
|
return await apiHelpers.postCommand(caller, 'downvote', 'voted', '', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
postsAPI.unvote = async function (caller, data) {
|
||||||
|
return await apiHelpers.postCommand(caller, 'unvote', 'voted', '', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
postsAPI.bookmark = async function (caller, data) {
|
||||||
|
return await apiHelpers.postCommand(caller, 'bookmark', 'bookmarked', '', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
postsAPI.unbookmark = async function (caller, data) {
|
||||||
|
return await apiHelpers.postCommand(caller, 'unbookmark', 'bookmarked', '', data);
|
||||||
|
};
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ const categories = require('../categories');
|
|||||||
const plugins = require('../plugins');
|
const plugins = require('../plugins');
|
||||||
const meta = require('../meta');
|
const meta = require('../meta');
|
||||||
const middleware = require('../middleware');
|
const middleware = require('../middleware');
|
||||||
const translator = require('../translator');
|
|
||||||
|
|
||||||
const isLanguageKey = /^\[\[[\w.\-_:]+]]$/;
|
|
||||||
const helpers = module.exports;
|
const helpers = module.exports;
|
||||||
|
|
||||||
helpers.noScriptErrors = async function (req, res, error, httpStatus) {
|
helpers.noScriptErrors = async function (req, res, error, httpStatus) {
|
||||||
@@ -349,12 +347,7 @@ helpers.formatApiResponse = async (statusCode, res, payload) => {
|
|||||||
response: payload || {},
|
response: payload || {},
|
||||||
});
|
});
|
||||||
} else if (payload instanceof Error) {
|
} else if (payload instanceof Error) {
|
||||||
let message = '';
|
const message = payload.message;
|
||||||
if (isLanguageKey.test(payload.message)) {
|
|
||||||
message = await translator.translate(payload.message, 'en-GB');
|
|
||||||
} else {
|
|
||||||
message = payload.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update status code based on some common error codes
|
// Update status code based on some common error codes
|
||||||
switch (payload.message) {
|
switch (payload.message) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ const posts = require('../../posts');
|
|||||||
const api = require('../../api');
|
const api = require('../../api');
|
||||||
const helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
const apiHelpers = require('../../api/helpers');
|
const apiHelpers = require('../../api/helpers');
|
||||||
const socketPostHelpers = require('../../socket.io/posts/helpers'); // eehhh...
|
|
||||||
|
|
||||||
const Posts = module.exports;
|
const Posts = module.exports;
|
||||||
|
|
||||||
@@ -37,43 +36,36 @@ Posts.delete = async (req, res) => {
|
|||||||
|
|
||||||
async function mock(req) {
|
async function mock(req) {
|
||||||
const tid = await posts.getPostField(req.params.pid, 'tid');
|
const tid = await posts.getPostField(req.params.pid, 'tid');
|
||||||
const data = { pid: req.params.pid, room_id: `topic_${tid}` };
|
return { pid: req.params.pid, room_id: `topic_${tid}` };
|
||||||
const socketMock = { uid: req.user.uid };
|
|
||||||
|
|
||||||
return { data, socketMock };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Posts.vote = async (req, res) => {
|
Posts.vote = async (req, res) => {
|
||||||
const { data, socketMock } = await mock(req);
|
const data = await mock(req);
|
||||||
|
|
||||||
if (req.body.delta > 0) {
|
if (req.body.delta > 0) {
|
||||||
await socketPostHelpers.postCommand(socketMock, 'upvote', 'voted', 'notifications:upvoted_your_post_in', data);
|
await api.posts.upvote(req, data);
|
||||||
} else if (req.body.delta < 0) {
|
} else if (req.body.delta < 0) {
|
||||||
await socketPostHelpers.postCommand(socketMock, 'downvote', 'voted', '', data);
|
await api.posts.downvote(req, data);
|
||||||
} else {
|
} else {
|
||||||
await socketPostHelpers.postCommand(socketMock, 'unvote', 'voted', '', data);
|
await api.posts.unvote(req, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
helpers.formatApiResponse(200, res);
|
helpers.formatApiResponse(200, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.unvote = async (req, res) => {
|
Posts.unvote = async (req, res) => {
|
||||||
const { data, socketMock } = await mock(req);
|
const data = await mock(req);
|
||||||
|
await api.posts.unvote(req, data);
|
||||||
await socketPostHelpers.postCommand(socketMock, 'unvote', 'voted', '', data);
|
|
||||||
helpers.formatApiResponse(200, res);
|
helpers.formatApiResponse(200, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.bookmark = async (req, res) => {
|
Posts.bookmark = async (req, res) => {
|
||||||
const { data, socketMock } = await mock(req);
|
const data = await mock(req);
|
||||||
|
await api.posts.bookmark(req, data);
|
||||||
await socketPostHelpers.postCommand(socketMock, 'bookmark', 'bookmarked', '', data);
|
|
||||||
helpers.formatApiResponse(200, res);
|
helpers.formatApiResponse(200, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.unbookmark = async (req, res) => {
|
Posts.unbookmark = async (req, res) => {
|
||||||
const { data, socketMock } = await mock(req);
|
const data = await mock(req);
|
||||||
|
await api.posts.unbookmark(req, data);
|
||||||
await socketPostHelpers.postCommand(socketMock, 'unbookmark', 'bookmarked', '', data);
|
|
||||||
helpers.formatApiResponse(200, res);
|
helpers.formatApiResponse(200, res);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
const helpers = require('./helpers');
|
|
||||||
const sockets = require('..');
|
const sockets = require('..');
|
||||||
|
const api = require('../../api');
|
||||||
|
|
||||||
module.exports = function (SocketPosts) {
|
module.exports = function (SocketPosts) {
|
||||||
SocketPosts.bookmark = async function (socket, data) {
|
SocketPosts.bookmark = async function (socket, data) {
|
||||||
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/bookmark');
|
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/bookmark');
|
||||||
return await helpers.postCommand(socket, 'bookmark', 'bookmarked', '', data);
|
return await api.posts.bookmark(socket, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketPosts.unbookmark = async function (socket, data) {
|
SocketPosts.unbookmark = async function (socket, data) {
|
||||||
sockets.warnDeprecated(socket, 'DELETE /api/v3/posts/:pid/bookmark');
|
sockets.warnDeprecated(socket, 'DELETE /api/v3/posts/:pid/bookmark');
|
||||||
return await helpers.postCommand(socket, 'unbookmark', 'bookmarked', '', data);
|
return await api.posts.unbookmark(socket, data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
const posts = require('../../posts');
|
|
||||||
const plugins = require('../../plugins');
|
|
||||||
const websockets = require('../index');
|
|
||||||
const socketHelpers = require('../helpers');
|
|
||||||
|
|
||||||
const helpers = module.exports;
|
|
||||||
|
|
||||||
helpers.postCommand = async function (socket, command, eventName, notification, data) {
|
|
||||||
if (!socket.uid) {
|
|
||||||
throw new Error('[[error:not-logged-in]]');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data || !data.pid) {
|
|
||||||
throw new Error('[[error:invalid-data]]');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.room_id) {
|
|
||||||
throw new Error('[[error:invalid-room-id, ' + data.room_id + ' ]]');
|
|
||||||
}
|
|
||||||
const [exists, deleted] = await Promise.all([
|
|
||||||
posts.exists(data.pid),
|
|
||||||
posts.getPostField(data.pid, 'deleted'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!exists) {
|
|
||||||
throw new Error('[[error:invalid-pid]]');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleted) {
|
|
||||||
throw new Error('[[error:post-deleted]]');
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
hooks:
|
|
||||||
filter:post.upvote
|
|
||||||
filter:post.downvote
|
|
||||||
filter:post.unvote
|
|
||||||
filter:post.bookmark
|
|
||||||
filter:post.unbookmark
|
|
||||||
*/
|
|
||||||
const filteredData = await plugins.fireHook('filter:post.' + command, { data: data, uid: socket.uid });
|
|
||||||
return await executeCommand(socket, command, eventName, notification, filteredData.data);
|
|
||||||
};
|
|
||||||
|
|
||||||
async function executeCommand(socket, command, eventName, notification, data) {
|
|
||||||
const result = await posts[command](data.pid, socket.uid);
|
|
||||||
if (result && eventName) {
|
|
||||||
websockets.in('uid_' + socket.uid).emit('posts.' + command, result);
|
|
||||||
websockets.in(data.room_id).emit('event:' + eventName, result);
|
|
||||||
}
|
|
||||||
if (result && command === 'upvote') {
|
|
||||||
socketHelpers.upvote(result, notification);
|
|
||||||
} else if (result && notification) {
|
|
||||||
socketHelpers.sendNotificationToPostOwner(data.pid, socket.uid, command, notification);
|
|
||||||
} else if (result && command === 'unvote') {
|
|
||||||
socketHelpers.rescindUpvoteNotification(data.pid, socket.uid);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ const user = require('../../user');
|
|||||||
const posts = require('../../posts');
|
const posts = require('../../posts');
|
||||||
const privileges = require('../../privileges');
|
const privileges = require('../../privileges');
|
||||||
const meta = require('../../meta');
|
const meta = require('../../meta');
|
||||||
const helpers = require('./helpers');
|
const api = require('../../api');
|
||||||
|
|
||||||
const sockets = require('..');
|
const sockets = require('..');
|
||||||
|
|
||||||
@@ -64,16 +64,16 @@ module.exports = function (SocketPosts) {
|
|||||||
|
|
||||||
SocketPosts.upvote = async function (socket, data) {
|
SocketPosts.upvote = async function (socket, data) {
|
||||||
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/vote');
|
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/vote');
|
||||||
return await helpers.postCommand(socket, 'upvote', 'voted', 'notifications:upvoted_your_post_in', data);
|
return await api.posts.upvote(socket, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketPosts.downvote = async function (socket, data) {
|
SocketPosts.downvote = async function (socket, data) {
|
||||||
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/vote');
|
sockets.warnDeprecated(socket, 'PUT /api/v3/posts/:pid/vote');
|
||||||
return await helpers.postCommand(socket, 'downvote', 'voted', '', data);
|
return await api.posts.downvote(socket, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketPosts.unvote = async function (socket, data) {
|
SocketPosts.unvote = async function (socket, data) {
|
||||||
sockets.warnDeprecated(socket, 'DELETE /api/v3/posts/:pid/vote');
|
sockets.warnDeprecated(socket, 'DELETE /api/v3/posts/:pid/vote');
|
||||||
return await helpers.postCommand(socket, 'unvote', 'voted', '', data);
|
return await api.posts.unvote(socket, data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user