From 713cc0cda18fc37265ce458e96b55cefef2ba04a Mon Sep 17 00:00:00 2001 From: David Jay Date: Wed, 7 Dec 2016 19:01:02 -0500 Subject: [PATCH] Posting actions to comment and user endpoints. --- .../coral-embed-stream/src/CommentStream.js | 4 +++- client/coral-framework/actions/items.js | 4 ++-- client/coral-plugin-flags/FlagButton.js | 20 ++++++++++++------- models/action.js | 8 +++++--- models/comment.js | 6 ++++-- models/user.js | 17 ++++++++++++++++ routes/api/comments/index.js | 5 +++-- routes/api/user/index.js | 18 +++++++++++++++++ 8 files changed, 65 insertions(+), 17 deletions(-) diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js index 7d1e20a09..93a2c186e 100644 --- a/client/coral-embed-stream/src/CommentStream.js +++ b/client/coral-embed-stream/src/CommentStream.js @@ -145,6 +145,7 @@ class CommentStream extends Component { ({ getStream: (rootId) => dispatch(getStream(rootId)), addNotification: (type, text) => dispatch(addNotification(type, text)), clearNotification: () => dispatch(clearNotification()), - postAction: (item, action, user, itemType, text) => dispatch(postAction(item, action, user, itemType, text)), + postAction: (item, action, user, itemType, field, detail) => dispatch(postAction(item, action, user, itemType, field, detail)), showSignInDialog: () => dispatch(showSignInDialog()), deleteAction: (item, action, user, itemType) => dispatch(deleteAction(item, action, user, itemType)), appendItemArray: (item, property, value, addToFront, itemType) => dispatch(appendItemArray(item, property, value, addToFront, itemType)), diff --git a/client/coral-framework/actions/items.js b/client/coral-framework/actions/items.js index 5ad709111..2a0c118a2 100644 --- a/client/coral-framework/actions/items.js +++ b/client/coral-framework/actions/items.js @@ -217,12 +217,12 @@ export function postItem (item, type, id) { * */ -export function postAction (item_id, action_type, user_id, item_type, text) { +export function postAction (item_id, action_type, user_id, item_type, field, detail) { return () => { const action = { action_type, user_id, - text + field, detail }; return coralApi(`/${item_type}/${item_id}/actions`, {method: 'POST', body: action}); diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js index baee12295..fcaa30b99 100644 --- a/client/coral-plugin-flags/FlagButton.js +++ b/client/coral-plugin-flags/FlagButton.js @@ -23,17 +23,18 @@ export default class FlagButton extends Component { } onPopupContinue = () => { - const {postAction, addItem, updateItem, currentUser, flag, id} = this.props; - const {itemType, reason, step} = this.state; + const {postAction, addItem, updateItem, currentUser, flag, id, author_id} = this.props; + const {itemType, field, detail, step} = this.state; this.setState({step: step + 1}); - if (itemType && reason) { - postAction(id, 'flag', currentUser.id, itemType, reason) + if (itemType && detail) { + const item_id = itemType === 'comments' ? id : author_id; + postAction(item_id, 'flag', currentUser.id, itemType, field, detail) .then((action) => { let id = `${action.action_type}_${action.item_id}`; addItem({id, current_user: action, count: flag ? flag.count + 1 : 1}, 'actions'); - updateItem(action.item_id, action.action_type, id, 'comments'); + updateItem(action.item_id, action.action_type, id, action.item_type); }); } } @@ -44,7 +45,7 @@ export default class FlagButton extends Component { return { header: 'Report an issue', options: [ - {val: 'users', text: 'Flag username'}, + {val: 'user', text: 'Flag username'}, {val: 'comments', text: 'Flag comment'}, ], button: 'Continue', @@ -69,7 +70,7 @@ export default class FlagButton extends Component { header: 'Help us understand', options, button: 'Continue', - sets: 'reason' + sets: 'detail' }; } case 3: { @@ -82,6 +83,11 @@ export default class FlagButton extends Component { onPopupOptionClick = (sets) => (e) => { this.setState({[sets]: e.target.value}); + + // If flagging a user, indicate that this is referencing the username rather than the bio + if(sets === 'itemType' && e.target.value === 'user') { + this.setState({field: 'username'}); + } } render () { diff --git a/models/action.js b/models/action.js index fa0892ffb..13b1c5494 100644 --- a/models/action.js +++ b/models/action.js @@ -13,7 +13,8 @@ const ActionSchema = new Schema({ item_type: String, item_id: String, user_id: String, - text: String, + field: String, // Used when an action references a particular field of an object. (e.g. a flag on a username or bio) + detail: String, // Describes the reason for an action (e.g. 'Username is offensive') }, { timestamps: { createdAt: 'created_at', @@ -36,13 +37,14 @@ ActionSchema.statics.findById = function(id) { * @param {String} action the new action to the comment * @return {Promise} */ -ActionSchema.statics.insertUserAction = ({item_id, item_type, user_id, action_type, text}) => { +ActionSchema.statics.insertUserAction = ({item_id, item_type, user_id, action_type, field, detail}) => { const action = { item_id, item_type, user_id, action_type, - text + field, + detail }; // Create/Update the action. diff --git a/models/comment.js b/models/comment.js index af9aa4cb1..80bfd67ea 100644 --- a/models/comment.js +++ b/models/comment.js @@ -284,11 +284,13 @@ CommentSchema.statics.pushStatus = (id, status, assigned_by = null) => Comment.u * @param {String} action the new action to the comment * @return {Promise} */ -CommentSchema.statics.addAction = (item_id, user_id, action_type) => Action.insertUserAction({ +CommentSchema.statics.addAction = (item_id, user_id, action_type, field, detail) => Action.insertUserAction({ item_id, item_type: 'comment', user_id, - action_type + action_type, + field, + detail }); /** diff --git a/models/user.js b/models/user.js index 336486a54..626b10e06 100644 --- a/models/user.js +++ b/models/user.js @@ -2,6 +2,7 @@ const mongoose = require('../mongoose'); const uuid = require('uuid'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); +const Action = require('./action'); // SALT_ROUNDS is the number of rounds that the bcrypt algorithm will run // through during the salting process. @@ -546,3 +547,19 @@ UserService.addBio = (id, bio) => ( new: true }) ); + +/** + * Add an action to the user. + * @param {String} item_id identifier of the user (uuid) + * @param {String} user_id user id of the action (uuid) + * @param {String} action the new action to the user + * @return {Promise} + */ +UserService.addAction = (item_id, user_id, action_type, field, detail) => Action.insertUserAction({ + item_id, + item_type: 'comment', + user_id, + action_type, + field, + detail +}); diff --git a/routes/api/comments/index.js b/routes/api/comments/index.js index b0b981fb3..25984405e 100644 --- a/routes/api/comments/index.js +++ b/routes/api/comments/index.js @@ -151,11 +151,12 @@ router.post('/:comment_id/actions', (req, res, next) => { const { action_type, - text + field, + detail } = req.body; Comment - .addAction(req.params.comment_id, req.user.id, action_type, text) + .addAction(req.params.comment_id, req.user.id, action_type, field, detail) .then((action) => { res.status(201).json(action); }) diff --git a/routes/api/user/index.js b/routes/api/user/index.js index 1765809ad..c5cf3d336 100644 --- a/routes/api/user/index.js +++ b/routes/api/user/index.js @@ -157,4 +157,22 @@ router.put('/:user_id/bio', (req, res, next) => { }); }); +router.post('/:user_id/actions', authorization.needed(), (req, res, next) => { + console.log('Hit action endpoint'); + const { + action_type, + field, + detail + } = req.body; + + User + .addAction(req.params.comment_id, req.user.id, action_type, field, detail) + .then((action) => { + res.status(201).json(action); + }) + .catch((err) => { + next(err); + }); +}); + module.exports = router;