mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 10:01:40 -05:00
improving notifications
This commit is contained in:
parent
497f4ca502
commit
2cfbcd2360
9 changed files with 62 additions and 40 deletions
|
@ -6,6 +6,9 @@ Setting = FormModel.extend({
|
||||||
requireViewInvite: false,
|
requireViewInvite: false,
|
||||||
requirePostInvite: false,
|
requirePostInvite: false,
|
||||||
requirePostsApproval: false,
|
requirePostsApproval: false,
|
||||||
|
emailNotifications: false,
|
||||||
|
nestedComments: false,
|
||||||
|
defaultEmail: '',
|
||||||
scoreUpdateInterval: '',
|
scoreUpdateInterval: '',
|
||||||
postInterval: '',
|
postInterval: '',
|
||||||
commentInterval: '',
|
commentInterval: '',
|
||||||
|
@ -15,10 +18,6 @@ Setting = FormModel.extend({
|
||||||
logoUrl: '',
|
logoUrl: '',
|
||||||
logoHeight: '',
|
logoHeight: '',
|
||||||
logoWidth: '',
|
logoWidth: '',
|
||||||
defaultEmail: '',
|
|
||||||
newPostsNotifications: false,
|
|
||||||
newRepliesNotifications: false,
|
|
||||||
nestedComments: false,
|
|
||||||
backgroundColor: '',
|
backgroundColor: '',
|
||||||
secondaryColor: '',
|
secondaryColor: '',
|
||||||
buttonColor: '',
|
buttonColor: '',
|
||||||
|
@ -39,8 +38,9 @@ Setting = FormModel.extend({
|
||||||
init: function(options) {
|
init: function(options) {
|
||||||
this._super(Settings, options);
|
this._super(Settings, options);
|
||||||
this.overwriteTitle('scoreUpdateInterval', 'Scoring Frequency');
|
this.overwriteTitle('scoreUpdateInterval', 'Scoring Frequency');
|
||||||
this.overwriteTitle('requireViewInvite', 'Require Invite to view?');
|
this.overwriteTitle('requireViewInvite', 'Require invite to view?');
|
||||||
this.overwriteTitle('requirePostInvite', 'Require Invite to post?');
|
this.overwriteTitle('requirePostInvite', 'Require invite to post?');
|
||||||
|
this.overwriteTitle('emailNotifications', 'Enable email notifications?');
|
||||||
this.overwriteTitle('requirePostsApproval', 'Posts must be approved by admin?');
|
this.overwriteTitle('requirePostsApproval', 'Posts must be approved by admin?');
|
||||||
this.overwriteTitle('title', 'Site Title');
|
this.overwriteTitle('title', 'Site Title');
|
||||||
this.overwriteTitle('mixpanelId', '<a href="http://mixpanel.com/">Mixpanel</a> ID');
|
this.overwriteTitle('mixpanelId', '<a href="http://mixpanel.com/">Mixpanel</a> ID');
|
||||||
|
|
|
@ -50,15 +50,15 @@
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">Email Notifications</label>
|
<label class="control-label">Email Notifications</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="radio">
|
<label class="checkbox">
|
||||||
<input id="notifications_activity" type="radio" value="1" name="notifications" {{hasNotificationsActivity}} /> When people reply to me
|
<input id="notifications_posts" type="checkbox" name="notifications_posts" {{hasNotificationsPosts}} /> New Posts
|
||||||
</label>
|
</label>
|
||||||
<label class="radio">
|
<label class="checkbox">
|
||||||
<input id="notifications_none" type="radio" value="0" name="notifications" {{hasNotificationsNone}} /> None
|
<input id="notifications_comments" type="checkbox" name="notifications_comments" {{hasNotificationsComments}} /> Comments on my posts
|
||||||
|
</label>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input id="notifications_replies" type="checkbox" name="notifications_replies" {{hasNotificationsReplies}} /> Replies to my comments
|
||||||
</label>
|
</label>
|
||||||
<!-- <label class="radio">
|
|
||||||
<input id="notifications_all" type="radio" value="2" name="notifications" {{hasNotificationsAll}} /> All
|
|
||||||
</label> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
|
|
|
@ -5,14 +5,14 @@ Template.user_edit.helpers({
|
||||||
userEmail : function(){
|
userEmail : function(){
|
||||||
return getEmail(this);
|
return getEmail(this);
|
||||||
},
|
},
|
||||||
hasNotificationsNone : function(){
|
hasNotificationsPosts : function(){
|
||||||
return this.profile && this.profile.notificationsFrequency == 0 ? 'checked' : '';
|
return getUserSetting('notifications.posts') ? 'checked' : '';
|
||||||
},
|
},
|
||||||
hasNotificationsActivity : function(){
|
hasNotificationsComments : function(){
|
||||||
return this.profile && (this.profile.notificationsFrequency == 1 || typeof this.profile.notificationsFrequency === 'undefined') ? 'checked' : '';
|
return getUserSetting('notifications.comments') ? 'checked' : '';
|
||||||
},
|
},
|
||||||
hasNotificationsAll : function(){
|
hasNotificationsReplies : function(){
|
||||||
return this.profile && this.profile.notificationsFrequency == 2 ? 'checked' : '';
|
return getUserSetting('notifications.replies') ? 'checked' : '';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -30,7 +30,9 @@ Template.user_edit.events = {
|
||||||
"profile.name": $target.find('[name=name]').val(),
|
"profile.name": $target.find('[name=name]').val(),
|
||||||
"profile.bio": $target.find('[name=bio]').val(),
|
"profile.bio": $target.find('[name=bio]').val(),
|
||||||
"profile.email": $target.find('[name=email]').val(),
|
"profile.email": $target.find('[name=email]').val(),
|
||||||
"profile.notificationsFrequency": parseInt($('input[name=notifications]:checked').val())
|
"profile.notifications.posts": $('input[name=notifications_posts]:checked').length,
|
||||||
|
"profile.notifications.comments": $('input[name=notifications_comments]:checked').length,
|
||||||
|
"profile.notifications.replies": $('input[name=notifications_replies]:checked').length
|
||||||
};
|
};
|
||||||
|
|
||||||
var old_password = $target.find('[name=old_password]').val();
|
var old_password = $target.find('[name=old_password]').val();
|
||||||
|
|
|
@ -41,7 +41,7 @@ Template.user_item.events({
|
||||||
if(error){
|
if(error){
|
||||||
throwError();
|
throwError();
|
||||||
}else{
|
}else{
|
||||||
Meteor.call('createNotification','accountApproved', {}, user);
|
Meteor.call('createNotification','accountApproved', {}, user, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,7 +17,6 @@ Comments.deny({
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
comment: function(postId, parentCommentId, text){
|
comment: function(postId, parentCommentId, text){
|
||||||
console.log('parentCommentId: '+parentCommentId)
|
|
||||||
var user = Meteor.user(),
|
var user = Meteor.user(),
|
||||||
post=Posts.findOne(postId),
|
post=Posts.findOne(postId),
|
||||||
postUser=Meteor.users.findOne(post.userId),
|
postUser=Meteor.users.findOne(post.userId),
|
||||||
|
@ -56,8 +55,7 @@ Meteor.methods({
|
||||||
comment.parent = parentCommentId;
|
comment.parent = parentCommentId;
|
||||||
|
|
||||||
var newCommentId=Comments.insert(comment);
|
var newCommentId=Comments.insert(comment);
|
||||||
console.log(comment)
|
|
||||||
console.log(newCommentId)
|
|
||||||
Posts.update(postId, {$inc: {comments: 1}});
|
Posts.update(postId, {$inc: {comments: 1}});
|
||||||
|
|
||||||
Meteor.call('upvoteComment', newCommentId);
|
Meteor.call('upvoteComment', newCommentId);
|
||||||
|
@ -74,19 +72,21 @@ Meteor.methods({
|
||||||
properties.parentAuthorId = parentComment.userId;
|
properties.parentAuthorId = parentComment.userId;
|
||||||
properties.parentAuthorName = getDisplayName(parentUser);
|
properties.parentAuthorName = getDisplayName(parentUser);
|
||||||
|
|
||||||
|
// reply notification
|
||||||
// do not notify users of their own actions (i.e. they're replying to themselves)
|
// do not notify users of their own actions (i.e. they're replying to themselves)
|
||||||
if(parentUser._id != user._id)
|
if(parentUser._id != user._id)
|
||||||
Meteor.call('createNotification','newReply', properties, parentUser, user);
|
Meteor.call('createNotification','newReply', properties, parentUser, user, getUserSetting('notifications.replies', false, parentUser));
|
||||||
|
|
||||||
|
// comment notification
|
||||||
// if the original poster is different from the author of the parent comment, notify them too
|
// if the original poster is different from the author of the parent comment, notify them too
|
||||||
if(postUser._id != user._id && parentComment.userId != post.userId)
|
if(postUser._id != user._id && parentComment.userId != post.userId)
|
||||||
Meteor.call('createNotification','newComment', properties, postUser, user);
|
Meteor.call('createNotification','newComment', properties, postUser, user, getUserSetting('notifications.comments', false, postUser));
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
// root comment
|
// root comment
|
||||||
// don't notify users of their own comments
|
// don't notify users of their own comments
|
||||||
if(postUser._id != user._id)
|
if(postUser._id != user._id)
|
||||||
Meteor.call('createNotification','newComment', properties, postUser, Meteor.user());
|
Meteor.call('createNotification','newComment', properties, postUser, Meteor.user(), getUserSetting('notifications.comments', false, postUser));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return properties;
|
return properties;
|
||||||
|
|
|
@ -83,8 +83,8 @@ Meteor.methods({
|
||||||
var postAuthor = Meteor.users.findOne(post.userId);
|
var postAuthor = Meteor.users.findOne(post.userId);
|
||||||
Meteor.call('upvotePost', postId,postAuthor);
|
Meteor.call('upvotePost', postId,postAuthor);
|
||||||
|
|
||||||
if(getSetting('newPostsNotifications')){
|
if(getSetting('emailNotifications', false)){
|
||||||
// notify admin of new posts
|
// notify users of new posts
|
||||||
var properties = {
|
var properties = {
|
||||||
postAuthorName : getDisplayName(postAuthor),
|
postAuthorName : getDisplayName(postAuthor),
|
||||||
postAuthorId : post.userId,
|
postAuthorId : post.userId,
|
||||||
|
@ -93,7 +93,7 @@ Meteor.methods({
|
||||||
}
|
}
|
||||||
var notification = getNotification('newPost', properties);
|
var notification = getNotification('newPost', properties);
|
||||||
// call a server method because we do not have access to admin users' info on the client
|
// call a server method because we do not have access to admin users' info on the client
|
||||||
Meteor.call('notifyAdmins', notification, Meteor.user(), function(error, result){
|
Meteor.call('notifyUsers', notification, Meteor.user(), function(error, result){
|
||||||
//run asynchronously
|
//run asynchronously
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
18
lib/users.js
18
lib/users.js
|
@ -76,4 +76,22 @@ numberOfItemsInPast24Hours = function(user, collection){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return items.count();
|
return items.count();
|
||||||
|
}
|
||||||
|
getUserSetting = function(setting, defaultValue, user){
|
||||||
|
var user = (typeof user == 'undefined') ? Meteor.user() : user;
|
||||||
|
var defaultValue = (typeof defaultValue == "undefined") ? null: defaultValue;
|
||||||
|
var settingValue = getProperty(user.profile, setting);
|
||||||
|
return (settingValue == null) ? defaultValue : settingValue;
|
||||||
|
}
|
||||||
|
getProperty = function(object, property){
|
||||||
|
// recursive function to get nested properties
|
||||||
|
var array = property.split('.');
|
||||||
|
if(array.length > 1){
|
||||||
|
var parent = array.shift();
|
||||||
|
// if our property is not at this level, call function again one level deeper if we can go deeper, else return null
|
||||||
|
return (typeof object[parent] == "undefined") ? null : getProperty(object[parent], array.join('.'))
|
||||||
|
}else{
|
||||||
|
// else return property
|
||||||
|
return object[array[0]];
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
sendEmail = function(to, subject, text, html){
|
sendEmail = function(to, subject, text, html){
|
||||||
|
|
||||||
// TO-DO: limit who can send emails
|
// TODO: limit who can send emails
|
||||||
|
// TODO: fix this error: Error: getaddrinfo ENOTFOUND
|
||||||
var from = getSetting('defaultEmail') || 'noreply@example.com';
|
|
||||||
|
var from = getSetting('defaultEmail', 'noreply@example.com');
|
||||||
var siteName = getSetting('title');
|
var siteName = getSetting('title');
|
||||||
var subject = '['+siteName+'] '+subject
|
var subject = '['+siteName+'] '+subject
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,12 @@ getUnsubscribeLink = function(user){
|
||||||
};
|
};
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
createNotification: function(event, properties, userToNotify, userDoingAction){
|
createNotification: function(event, properties, userToNotify, userDoingAction, sendEmail){
|
||||||
// console.log('adding new notification for:'+getDisplayName(userToNotify)+', for event:'+event);
|
// console.log('adding new notification for:'+getDisplayName(userToNotify)+', for event:'+event);
|
||||||
// console.log(userToNotify);
|
// console.log(userToNotify);
|
||||||
// console.log(userDoingAction);
|
// console.log(userDoingAction);
|
||||||
// console.log(properties);
|
// console.log(properties);
|
||||||
|
// console.log(sendEmail);
|
||||||
var notification= {
|
var notification= {
|
||||||
timestamp: new Date().getTime(),
|
timestamp: new Date().getTime(),
|
||||||
userId: userToNotify._id,
|
userId: userToNotify._id,
|
||||||
|
@ -19,7 +20,7 @@ Meteor.methods({
|
||||||
|
|
||||||
// send the notification if notifications are activated,
|
// send the notification if notifications are activated,
|
||||||
// the notificationsFrequency is set to 1, or if it's undefined (legacy compatibility)
|
// the notificationsFrequency is set to 1, or if it's undefined (legacy compatibility)
|
||||||
if(userToNotify.profile && (userToNotify.profile.notificationsFrequency === 1 || typeof userToNotify.profile.notificationsFrequency === 'undefined')){
|
if(sendEmail){
|
||||||
Meteor.call('sendNotificationEmail', userToNotify, newNotificationId);
|
Meteor.call('sendNotificationEmail', userToNotify, newNotificationId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -45,11 +46,11 @@ Meteor.methods({
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
notifyAdmins : function(notification, currentUser){
|
notifyUsers : function(notification, currentUser){
|
||||||
// send a notification to every site admin
|
// send a notification to every user according to their notifications settings
|
||||||
_.each(adminUsers(), function(user, index, list){
|
_.each(Meteor.users.find().fetch(), function(user, index, list){
|
||||||
if(user._id !== currentUser._id){
|
if(user._id !== currentUser._id && getUserSetting('notifications.posts', false, user)){
|
||||||
// don't send admins notifications for their own posts
|
// don't send users notifications for their own posts
|
||||||
sendEmail(getEmail(user), notification.subject, notification.text, notification.html);
|
sendEmail(getEmail(user), notification.subject, notification.text, notification.html);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue