Skip to content

Commit

Permalink
refactor: posts api
Browse files Browse the repository at this point in the history
  • Loading branch information
barisusakli committed Oct 18, 2020
1 parent 272e73d commit d9a1685
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 123 deletions.
24 changes: 6 additions & 18 deletions public/src/client/topic/votes.js
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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');
}
});
Expand Down
8 changes: 1 addition & 7 deletions public/src/modules/api.js
Expand Up @@ -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));
});
}

Expand Down
60 changes: 59 additions & 1 deletion src/api/helpers.js
Expand Up @@ -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
Expand Down Expand Up @@ -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]]');
Expand Down Expand Up @@ -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;
}
19 changes: 19 additions & 0 deletions src/api/posts.js
Expand Up @@ -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);
};
9 changes: 1 addition & 8 deletions src/controllers/helpers.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
30 changes: 11 additions & 19 deletions src/controllers/write/posts.js
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
};
7 changes: 3 additions & 4 deletions src/socket.io/posts/bookmarks.js
@@ -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);
};
};
62 changes: 0 additions & 62 deletions src/socket.io/posts/helpers.js

This file was deleted.

8 changes: 4 additions & 4 deletions src/socket.io/posts/votes.js
Expand Up @@ -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('..');

Expand Down Expand Up @@ -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);
};
};

0 comments on commit d9a1685

Please sign in to comment.