Skip to content

Commit

Permalink
Merge 5394e07 into 9b7a8bb
Browse files Browse the repository at this point in the history
  • Loading branch information
chuxmykel committed Aug 8, 2019
2 parents 9b7a8bb + 5394e07 commit da16ccf
Show file tree
Hide file tree
Showing 22 changed files with 798 additions and 16 deletions.
5 changes: 4 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ SERVER_MAIL = noreply@authorsHaven.com
CLOUD_NAME = Your cloudinary cloud name
CLOUD_API_KEY = Your cloudinary api key
CLOUD_API_SECRET = Your cloudinary api secret

PUSHER_APP_ID=YOUR_APP_ID
PUSHER_APP_KEY=YOUR_APP_KEY
PUSHER_APP_SECRET=YOUR_APP_SECRET
PUSHER_APP_CLUSTER=YOUR_APP_CLUSTER
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"seed:undo": "node_modules/.bin/sequelize db:seed:undo:all",
"generate:model": "node_modules/.bin/sequelize model:generate",
"generate:migration": "node_modules/.bin/sequelize migration:generate",
"generate:seed": "node_modules/.bin/sequelize seed:generate",
"migrate": "node_modules/.bin/sequelize db:migrate",
"migrate:undo": "node_modules/.bin/sequelize db:migrate:undo:all",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
Expand Down Expand Up @@ -54,6 +55,7 @@
"passport-google-oauth2": "^0.2.0",
"pg": "^7.11.0",
"pg-hstore": "^2.3.3",
"pusher": "^2.2.2",
"sequelize": "^5.10.2",
"sequelize-cli": "^5.5.0",
"sequelize-slugify": "^0.7.0",
Expand Down
20 changes: 19 additions & 1 deletion server/controllers/articleController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import sequelize from 'sequelize';
import models from '../db/models';
import helpers from '../helpers';
import Paginate from '../helpers/paginate';
import Notification from '../helpers/notifications';

const { Op } = sequelize;
const { paginateArticles } = Paginate;
Expand Down Expand Up @@ -35,7 +36,6 @@ class ArticleController {
image
} = req.body.article;
const readTime = Math.floor(articleBody.split(' ').length / 200);

const article = await models.Article.create({
title,
description,
Expand All @@ -47,6 +47,24 @@ class ArticleController {
readTime
});
article.tagList = [...article.dataValues.tagList.split(' ')];
const author = await article.getAuthor({
attributes: ['username'],
include: [{
model: models.User,
through: {
attributes: []
},
as: 'followers',
attributes: ['id', 'username', 'email', 'newPostEmailSub'],
}],
});

const payload = {
resourceType: 'article',
resourceId: article.slug,
message: `${author.username} just posted a new article`,
};
Notification.notify(author.followers, payload);
return successStat(res, 201, 'articles', article);
}

Expand Down
10 changes: 10 additions & 0 deletions server/controllers/commentController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Sequelize from 'sequelize';
import models from '../db/models';
import helpers from '../helpers';
import Notification from '../helpers/notifications';

const { successStat, errorStat } = helpers;

Expand Down Expand Up @@ -45,6 +46,15 @@ export default class CommentController {
]
}
});
const author = await post.getAuthor({
attributes: ['id', 'username', 'email', 'newPostEmailSub']
});
const payload = {
resourceType: 'comment',
resourceId: post.slug,
message: `${commentResponse.author.username} commented on your article`,
};
Notification.notify([author], payload);
return successStat(res, 201, 'comment', commentResponse);
}

Expand Down
76 changes: 76 additions & 0 deletions server/controllers/notificationController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import sequelize from 'sequelize';
import models from '../db/models';
import helpers from '../helpers';

const { Op } = sequelize;
const { successStat } = helpers;

/**
* @Module NotificationController
* @description Controlls comments made by users
*/
class NotificationController {
/**
* @static
* @param {*} req Request object
* @param {*} res Response object
* @returns {Object} server response
* @memberof NotificationController
*/
static async getNotifications(req, res) {
const { user: { id } } = req;
const user = await models.User.findByPk(id);
return successStat(res, 200, 'notifications', await user.getNotifications());
}

/**
* @static
* @param {*} req Request object
* @param {*} res Response object
* @returns {Object} server response
* @memberof NotificationController
*/
static async markAsRead(req, res) {
const { user: { id }, params, } = req;
await models.Notification.update({
read: true,
}, {
where: {
[Op.and]: [{ id: params.id }, { userId: id }]
}
});
return successStat(res, 200, 'message', 'marked as read');
}

/**
* @static
* @param {*} req Request object
* @param {*} res Response object
* @returns {Object} server response
* @memberof NotificationController
*/
static async markAllAsRead(req, res) {
const { id } = req.user;
await models.Notification.update({ read: true }, {
where: {
userId: id,
}
});
return successStat(res, 200, 'message', 'all notifications marked as read');
}

/**
* @static
* @param {*} req Request object
* @param {*} res Response object
* @returns {Object} server response
* @memberof NotificationController
*/
static async emailSubscribe(req, res) {
const { user: { id }, method } = req;
await models.User.update({ newPostEmailSub: method === 'PATCH', }, { where: { id } });
return successStat(res, 200, 'message', `email notification ${method === 'PATCH' ? 'enabled' : 'disabled'}`);
}
}

export default NotificationController;
45 changes: 45 additions & 0 deletions server/db/migrations/20190806103204-create-notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Notifications', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'Users',
key: 'id',
},
onDelete: 'CASCADE'
},
resourceType: {
type: Sequelize.STRING,
allowNull: false,
},
resourceId: {
type: Sequelize.STRING,
allowNull: false,
},
message: {
type: Sequelize.STRING,
allowNull: false,
},
read: {
type: Sequelize.BOOLEAN,
allowNull: false,
default: false,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('Notifications')
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.addColumn('Users', 'newPostEmailSub', {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: true
}),
down: queryInterface => queryInterface.removeColumn('Users', 'newPostEmailSub')
};
16 changes: 16 additions & 0 deletions server/db/models/notification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = (sequelize, DataTypes) => {
const Notification = sequelize.define('Notification', {
userId: DataTypes.INTEGER,
resourceType: DataTypes.STRING,
resourceId: DataTypes.STRING,
message: DataTypes.STRING,
read: DataTypes.BOOLEAN,
}, {});
Notification.associate = (models) => {
Notification.belongsTo(models.User, {
as: 'userNotification',
foreignKey: 'userId',
});
};
return Notification;
};
4 changes: 2 additions & 2 deletions server/db/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = (sequelize, DataTypes) => {
image: DataTypes.STRING,
socialId: DataTypes.STRING,
verified: DataTypes.BOOLEAN,
newPostEmailSub: DataTypes.BOOLEAN,
}, {});
User.associate = (models) => {
User.belongsToMany(models.User, {
Expand Down Expand Up @@ -37,12 +38,11 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'userId',
onDelete: 'CASCADE'
});
User.hasMany(models.Article, { as: 'authorId', foreignKey: 'authorId', onDelete: 'CASCADE' });
User.hasMany(models.Comment, { foreignKey: 'authorId', onDelete: 'CASCADE' });
User.hasMany(models.Article, { foreignKey: 'authorId', onDelete: 'CASCADE' });
User.hasMany(models.Likes, {
foreignKey: 'userId', as: 'likes', timestamps: false, onDelete: 'CASCADE'
});
User.hasMany(models.Notification, { foreignKey: 'userId', onDelete: 'CASCADE' });
};
return User;
};
12 changes: 12 additions & 0 deletions server/db/seeders/20190731122700-demo-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: true,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -19,6 +20,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -30,6 +32,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: true,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -41,6 +44,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: true,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -52,6 +56,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: true,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -63,6 +68,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -74,6 +80,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: true,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -85,6 +92,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -96,6 +104,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -107,6 +116,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -118,6 +128,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand All @@ -129,6 +140,7 @@ module.exports = {
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
createdAt: new Date(),
updatedAt: new Date(),
},
Expand Down
Loading

0 comments on commit da16ccf

Please sign in to comment.