Skip to content

Commit

Permalink
Merge 2639fbf into 7c55f1a
Browse files Browse the repository at this point in the history
  • Loading branch information
akpante3 committed Dec 20, 2018
2 parents 7c55f1a + 2639fbf commit 2d9e53d
Show file tree
Hide file tree
Showing 31 changed files with 1,244 additions and 548 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ node_modules
# Build
dist/
.vscode/settings.json
. editorconfig
.editorconfig
client/
3 changes: 2 additions & 1 deletion controllers/ArticlesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '../helpers/articleHelper';
import ReadingStatsModelQuery from '../lib/ReadingStatsModelQuery';
import eventEmitter from '../helpers/eventEmitter';
import eventTypes from '../events/eventTypes';

const { articles: Article, tags: Tag, HighlightedText } = models;

Expand Down Expand Up @@ -185,7 +186,7 @@ class ArticlesController {

// Use an event emitter to call updateHighlights
eventEmitter.emit(
'UPDATEHIGHLIGHT',
eventTypes.UPDATEHIGHLIGHT_EVENT,
article.highlightedPortions,
updatedArticle[1][0].body,
userId
Expand Down
14 changes: 14 additions & 0 deletions controllers/CommentController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Op } from 'sequelize';
import db from '../models';
import StatusResponse from '../helpers/StatusResponse';
import eventEmitter from '../helpers/eventEmitter';
import ArticleQueryModel from '../lib/ArticleQueryModel';
import eventTypes from '../events/eventTypes';

const { comments, profiles } = db;
/**
Expand All @@ -23,6 +26,17 @@ class CommentController {
articleId,
content
});
// event emitter
const articleOwner = await ArticleQueryModel.getArticleByIdentifier({ id: articleId });

eventEmitter.emit(eventTypes.COMMENT_NOTIFICATION_EVENT, {
to: articleOwner.dataValues,
from: userId,
articleId: req.params.articleId,
type: 'comment',
event: comment.dataValues
});

const payload = {
message: 'Comment has been successfully created',
comment
Expand Down
8 changes: 8 additions & 0 deletions controllers/FollowersController.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import model from '../models';
import StatusResponse from '../helpers/StatusResponse';
import ProfilesModelQuery from '../lib/ProfilesModelQuery';
import FollowersModelQuery from '../lib/FollowersModelQuery';
import eventEmitter from '../helpers/eventEmitter';
import eventTypes from '../events/eventTypes';


const { followers } = model;

Expand Down Expand Up @@ -50,6 +53,11 @@ class FollowersController {
});

if (followUser) {
eventEmitter.emit(eventTypes.FOLLOW_INTERACTION_EVENT, {
to: intFollowId,
from: userId,
type: 'follow'
});
return StatusResponse.success(res, {
message: 'User followed successfully',
});
Expand Down
23 changes: 13 additions & 10 deletions controllers/LikesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ class LikesController {
static async likesArticles(req, res) {
const { articleId } = req.params;
const { userId } = req.app.locals.user;
const payload = {
articleId,
userId,
commentId: null
};

try {
const articleOwner = await ArticleQueryModel.getArticleByIdentifier({ id: articleId });
const payload = {
articleOwner,
articleId,
userId,
commentId: null
};
await like(res, payload);
} catch (error) {
StatusResponse.internalServerError(res, { message: 'server error' });
Expand All @@ -37,23 +38,25 @@ class LikesController {
* @public
*/
static async likesComments(req, res) {
const { commentId } = req.params;
const { commentId, articleId } = req.params;
const { userId } = req.app.locals.user;
const articleOwner = await ArticleQueryModel.getArticleByIdentifier({ id: articleId });
const payload = {
articleId: null,
userId,
commentId,
articleOwner
};

try {
const ifExist = await ArticleQueryModel.getCommentById(commentId);
if (!ifExist) {
return StatusResponse.notfound(res, { message: 'comment was not found' });
}
const likeComment = await like(res, payload);
return likeComment;
await like(res, payload);
return StatusResponse.success(res, { message: 'comment was liked successfully' });
} catch (error) {
return StatusResponse.internalServerError(res, { message: 'server error' });
return StatusResponse.internalServerError(res, { message: 'server errorrrr' });
}
}

Expand Down
85 changes: 85 additions & 0 deletions controllers/NotificationsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Model from '../models';
import StatusResponse from '../helpers/StatusResponse';
import { findNotificationById } from '../lib/notifications';

const { notifications } = Model;
/** @description NotificationsController class
* @return {object} the response object
* @public
*/
class NotificationsController {
/** @description function to like an article
* @param {string} req is the request parameter
* @param {string} res is the response parameter
* @return {object} the response object
* @public
*/
static async getUsersNotification(req, res) {
const { userId } = req.params;
const user = req.app.locals.user.userId;
if (user !== parseInt(userId, 10)) {
return StatusResponse.unauthorized(res, { message: 'access cannot be granted' });
}
const findNotifications = await notifications.findAndCountAll({
where: {
userId
}
});
if (findNotifications) {
return StatusResponse.success(res, findNotifications);
}
return StatusResponse.notfound(res, { message: 'no notificationa found' });
}

/** @description function get one notification
* @param {string} req is the request parameter
* @param {string} res is the response parameter
* @return {object} the response object
* @public
*/
static async getOneNotification(req, res) {
const { notificationId, userId } = req.params;
const user = req.app.locals.user.userId;

if (user !== parseInt(userId, 10)) {
return StatusResponse.unauthorized(res, { message: 'access cannot be granted' });
}
const findNotifications = await notifications.findOne({
where: {
id: notificationId
}
});
if (findNotifications) {
return StatusResponse.success(res, findNotifications);
}
return StatusResponse.notfound(res, { message: 'notification was found' });
}

/** @description function get one notification
* @param {string} req is the request parameter
* @param {string} res is the response parameter
* @return {object} the response object
* @public
*/
static async updateNotification(req, res) {
const { notificationId, userId } = req.params;
const user = req.app.locals.user.userId;
try {
if (user !== parseInt(userId, 10)) {
return StatusResponse.unauthorized(res, { message: 'access cannot be granted' });
}
const notification = await findNotificationById(notificationId);
if (notification) {
await notification.update({
isRead: true
});
return StatusResponse.success(res, { message: 'notification was updated successfully' });
}
return StatusResponse.notfound(res, { message: 'no notification found' });
} catch (error) {
return StatusResponse.internalServerError(res, { message: 'server error' });
}
}
}

export default NotificationsController;
18 changes: 17 additions & 1 deletion controllers/RatingsController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import model from '../models';
import StatusResponse from '../helpers/StatusResponse';
import ArticleQueryModel from '../lib/ArticleQueryModel';
import eventEmitter from '../helpers/eventEmitter';
import eventTypes from '../events/eventTypes';

const { ratings } = model;

Expand All @@ -17,12 +20,25 @@ class RatingsController {
* @returns {object} Users Ratings on an article
*/
static async create(req, res) {
const { userId } = req.app.locals.user;
try {
const usersRatings = await ratings.create({
userId: req.userId,
userId,
articleId: req.params.articleId,
stars: req.body.stars
});

const articleOwner = await ArticleQueryModel.getArticleByIdentifier({
id: req.params.articleId
});
eventEmitter.emit(eventTypes.RATING_INTERACTION_EVENT, {
to: articleOwner.dataValues,
from: userId,
articleId: req.params.articleId,
type: 'rating',
event: usersRatings.dataValues
});

StatusResponse.created(res, {
message: 'Users ratings on this article recorded succesfully',
ratings: usersRatings
Expand Down
14 changes: 14 additions & 0 deletions controllers/RepliesController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import StatusResponse from '../helpers/StatusResponse';
import ReplyQueryModel from '../lib/ReplyQueryModel';
import eventEmitter from '../helpers/eventEmitter';
import eventTypes from '../events/eventTypes';
import ArticleQueryModel from '../lib/ArticleQueryModel';


/**
* @description RepliesController class
Expand All @@ -22,6 +26,16 @@ class RepliesController {
userId
};
const replies = await ReplyQueryModel.createReplies(info);
// event emitter
const commentOwner = await ArticleQueryModel.getArticleByIdentifier({ id: commentId });

eventEmitter.emit(eventTypes.COMMENT_NOTIFICATION_EVENT, {
to: commentOwner.dataValues,
from: userId,
articleId: req.params.commentId,
type: 'comment',
event: replies.dataValues
});
const payload = {
message: 'Reply has been successfully created',
replies
Expand Down
75 changes: 75 additions & 0 deletions events/Notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import UsermodelQuery from '../lib/UserModelQuery';
import mailer from '../helpers/mailer';
import { createNotification } from '../lib/notifications';

/** @description Notifications class
* @public
*/
class Notifications {
/** @description function to add a notification
* @param {object} payload is the response parameter
* @param {object} io is the response parameter
* @return {object} the response object
* @public
*/
static async addNotification(payload, io) {
try {
const {
to: { userId, title, slug }, type, from: user, event: { createdAt, id }
} = payload;
const articleOwner = await UsermodelQuery.getUserById(userId);
const sender = await UsermodelQuery.getUserById(user);
const { dataValues: { email } } = articleOwner;
const { profile: { dataValues: { username } } } = sender;
const info = {
title,
type,
link: slug,
userId,
senderUsername: username,
senderId: user,
event: { createdAt, id }
};
const created = await createNotification(info);
if (created) {
await mailer.sendNotificationMail(email, username, info);
return io.emit('Notification Created', info);
}
return false;
} catch (error) {
return error;
}
}

/** @description function to add a follow notification
* @param {object} payload is the response parameter
* @param {object} io is the response parameter
* @return {object} the response object
* @public
*/
static async followNotification(payload, io) {
try {
const { to: intFollowId, type, from: userId } = payload;
const followed = await UsermodelQuery.getUserById(intFollowId);
const follower = await UsermodelQuery.getUserById(userId);
const { dataValues: { email } } = followed;
const { profile: { dataValues: { username } } } = follower;
const info = {
title: 'followed',
type,
userId,
senderId: intFollowId,
link: ''
};
const created = await createNotification(info);
if (created) {
await mailer.sendNotificationMail(email, username, info);
return io.emit('Notification Created', info);
}
return false;
} catch (error) {
return error;
}
}
}
export default Notifications;
9 changes: 9 additions & 0 deletions events/eventTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


export default {
ARTICLE_NOTIFICATION_EVENT: 'ARTICLE_NOTIFICATION_EVENT',
COMMENT_NOTIFICATION_EVENT: 'COMMENT_NOTIFICATION_EVENT',
RATING_INTERACTION_EVENT: 'RATING_INTERACTION_EVENT,',
FOLLOW_INTERACTION_EVENT: 'FOLLOW_INTERACTION_EVENT',
UPDATEHIGHLIGHT_EVENT: 'UPDATEHIGHLIGHT_EVENT'
};
29 changes: 29 additions & 0 deletions events/handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import eventEmitter from '../helpers/eventEmitter';
import Notifications from './Notifications';
import eventTypes from './eventTypes';
import highlightsLogic from '../lib/highlightsLogic';

const { updateHighlights } = highlightsLogic;


const handlers = {
register(io) {
eventEmitter.on(eventTypes.ARTICLE_NOTIFICATION_EVENT,
payload => Notifications.addNotification(payload, io));

eventEmitter.on(eventTypes.COMMENT_NOTIFICATION_EVENT,
payload => Notifications.addNotification(payload, io));

eventEmitter.on(eventTypes.RATING_INTERACTION_EVENT,
payload => Notifications.addNotification(payload, io));

eventEmitter.on(eventTypes.FOLLOW_INTERACTION_EVENT,
payload => Notifications.followNotification(payload, io));

eventEmitter.on(eventTypes.UPDATEHIGHLIGHT_EVENT, (highlightedPortions, body, userId) => {
updateHighlights(highlightedPortions, body, userId);
});
}
};

export default handlers;
Loading

0 comments on commit 2d9e53d

Please sign in to comment.