mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 03:55:55 +01:00
refactor: posts api
This commit is contained in:
@@ -8,15 +8,6 @@ define('forum/topic/votes', [
|
||||
|
||||
Votes.addVoteHandler = function () {
|
||||
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) {
|
||||
@@ -26,18 +17,14 @@ define('forum/topic/votes', [
|
||||
var el = $this.parent();
|
||||
var pid = el.parents('[data-pid]').attr('data-pid');
|
||||
|
||||
$('.tooltip').tooltip('destroy');
|
||||
$this.off('mouseenter', loadDataAndCreateTooltip);
|
||||
|
||||
socket.emit('posts.getUpvoters', [pid], function (err, data) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
if (data.length) {
|
||||
createTooltip(el, data[0]);
|
||||
createTooltip($this, data[0]);
|
||||
}
|
||||
$this.off('mouseenter').on('mouseenter', loadDataAndCreateTooltip);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
@@ -46,7 +33,8 @@ define('forum/topic/votes', [
|
||||
function doCreateTooltip(title) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@@ -70,10 +58,10 @@ define('forum/topic/votes', [
|
||||
const method = currentState ? 'del' : 'put';
|
||||
api[method](`/posts/${post.attr('data-pid')}/vote`, {
|
||||
delta: delta,
|
||||
}, undefined, (err) => {
|
||||
app.alertError(err.status.message);
|
||||
}).catch((err) => {
|
||||
app.alertError(err.message);
|
||||
|
||||
if (err.status.message === '[[error:not-logged-in]]') {
|
||||
if (err.message === '[[error:not-logged-in]]') {
|
||||
ajaxify.go('login');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -22,13 +22,7 @@ define('api', () => {
|
||||
ev.responseJSON.status.message :
|
||||
ev.responseJSON.error;
|
||||
|
||||
const error = new Error(errMessage || ev.statusText);
|
||||
|
||||
if (!utils.hasLanguageKey(error.message)) {
|
||||
app.alertError(error.message);
|
||||
}
|
||||
|
||||
cb(error);
|
||||
cb(new Error(errMessage || ev.statusText));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
const url = require('url');
|
||||
const user = require('../user');
|
||||
const topics = require('../topics');
|
||||
const posts = require('../posts');
|
||||
const privileges = require('../privileges');
|
||||
const plugins = require('../plugins');
|
||||
const socketHelpers = require('../socket.io/helpers');
|
||||
const websockets = require('../socket.io');
|
||||
const events = require('../events');
|
||||
|
||||
// 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 }) {
|
||||
if (!Array.isArray(tids)) {
|
||||
throw new Error('[[error:invalid-tid]]');
|
||||
@@ -73,3 +75,59 @@ async function logTopicAction(action, req, tid, 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 meta = require('../meta');
|
||||
const middleware = require('../middleware');
|
||||
const translator = require('../translator');
|
||||
|
||||
const isLanguageKey = /^\[\[[\w.\-_:]+]]$/;
|
||||
const helpers = module.exports;
|
||||
|
||||
helpers.noScriptErrors = async function (req, res, error, httpStatus) {
|
||||
@@ -349,12 +347,7 @@ helpers.formatApiResponse = async (statusCode, res, payload) => {
|
||||
response: payload || {},
|
||||
});
|
||||
} else if (payload instanceof Error) {
|
||||
let message = '';
|
||||
if (isLanguageKey.test(payload.message)) {
|
||||
message = await translator.translate(payload.message, 'en-GB');
|
||||
} else {
|
||||
message = payload.message;
|
||||
}
|
||||
const message = payload.message;
|
||||
|
||||
// Update status code based on some common error codes
|
||||
switch (payload.message) {
|
||||
|
||||
@@ -5,7 +5,6 @@ const posts = require('../../posts');
|
||||
const api = require('../../api');
|
||||
const helpers = require('../helpers');
|
||||
const apiHelpers = require('../../api/helpers');
|
||||
const socketPostHelpers = require('../../socket.io/posts/helpers'); // eehhh...
|
||||
|
||||
const Posts = module.exports;
|
||||
|
||||
@@ -37,43 +36,36 @@ Posts.delete = async (req, res) => {
|
||||
|
||||
async function mock(req) {
|
||||
const tid = await posts.getPostField(req.params.pid, 'tid');
|
||||
const data = { pid: req.params.pid, room_id: `topic_${tid}` };
|
||||
const socketMock = { uid: req.user.uid };
|
||||
|
||||
return { data, socketMock };
|
||||
return { pid: req.params.pid, room_id: `topic_${tid}` };
|
||||
}
|
||||
|
||||
Posts.vote = async (req, res) => {
|
||||
const { data, socketMock } = await mock(req);
|
||||
|
||||
const data = await mock(req);
|
||||
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) {
|
||||
await socketPostHelpers.postCommand(socketMock, 'downvote', 'voted', '', data);
|
||||
await api.posts.downvote(req, data);
|
||||
} else {
|
||||
await socketPostHelpers.postCommand(socketMock, 'unvote', 'voted', '', data);
|
||||
await api.posts.unvote(req, data);
|
||||
}
|
||||
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Posts.unvote = async (req, res) => {
|
||||
const { data, socketMock } = await mock(req);
|
||||
|
||||
await socketPostHelpers.postCommand(socketMock, 'unvote', 'voted', '', data);
|
||||
const data = await mock(req);
|
||||
await api.posts.unvote(req, data);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Posts.bookmark = async (req, res) => {
|
||||
const { data, socketMock } = await mock(req);
|
||||
|
||||
await socketPostHelpers.postCommand(socketMock, 'bookmark', 'bookmarked', '', data);
|
||||
const data = await mock(req);
|
||||
await api.posts.bookmark(req, data);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
Posts.unbookmark = async (req, res) => {
|
||||
const { data, socketMock } = await mock(req);
|
||||
|
||||
await socketPostHelpers.postCommand(socketMock, 'unbookmark', 'bookmarked', '', data);
|
||||
const data = await mock(req);
|
||||
await api.posts.unbookmark(req, data);
|
||||
helpers.formatApiResponse(200, res);
|
||||
};
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
const helpers = require('./helpers');
|
||||
const sockets = require('..');
|
||||
const api = require('../../api');
|
||||
|
||||
module.exports = function (SocketPosts) {
|
||||
SocketPosts.bookmark = async function (socket, data) {
|
||||
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) {
|
||||
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 privileges = require('../../privileges');
|
||||
const meta = require('../../meta');
|
||||
const helpers = require('./helpers');
|
||||
const api = require('../../api');
|
||||
|
||||
const sockets = require('..');
|
||||
|
||||
@@ -64,16 +64,16 @@ module.exports = function (SocketPosts) {
|
||||
|
||||
SocketPosts.upvote = async function (socket, data) {
|
||||
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) {
|
||||
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) {
|
||||
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