Merge remote-tracking branch 'origin/master' into 0.7.0

v1.18.x
barisusakli 10 years ago
commit 20a2262e43

@ -1,3 +1,14 @@
# Submitting a Pull Request to NodeBB?
First of all, thank you! Please consider this [style guide](https://docs.nodebb.org/en/latest/contributing/style-guide.html) when submitting your changes. Also, please join our [community](https://community.nodebb.org) to meet other NodeBB developers and designers :)
## Contributor License Agreement
Thank you for considering contributing to NodeBB. **Before we can accept any pull requests, please take a moment to read and sign our [license agreement](https://www.clahub.com/agreements/NodeBB/NodeBB)**. In summary, signing this document means that 1) you own the code that you are contributing and 2) you give permission to NodeBB Inc. to license the code to others. This agreement applies to any repository under the NodeBB organization.
If you are writing contributions as part of employment from another company / individual, then your employer will need to sign a separate agreement. Please [contact us](mailto:accounts@nodebb.org) so that we can send this additional agreement to your employer.
# Having problems installing NodeBB?
Chances are somebody has run into this problem before. After consulting our [documentation](https://docs.nodebb.org/en/latest/installing/os.html), please head over to our [community support forum](https://community.nodebb.org) for advice.
@ -44,8 +55,3 @@ If you have downloaded the `.zip` or `.tar.gz` packages from GitHub (or elsewher
If you have installed NodeBB via GitHub clone, are familiar with utilising git, and are willing to help us narrow down the specific commit that causes a bug, consider running `git bisect`.
A full guide can be found here: [Debugging with Git/Binary Search](http://git-scm.com/book/en/Git-Tools-Debugging-with-Git#Binary-Search)
# Submitting a Pull Request to NodeBB?
First of all, thank you! Please consider this [style guide](https://docs.nodebb.org/en/latest/contributing/style-guide.html) when submitting your changes. Also, please join our [community](https://community.nodebb.org) to meet other NodeBB developers and designers :)

@ -38,7 +38,7 @@
"nconf": "~0.7.1",
"nodebb-plugin-dbsearch": "^0.1.0",
"nodebb-plugin-markdown": "^0.8.0",
"nodebb-plugin-mentions": "^0.7.0",
"nodebb-plugin-mentions": "^0.9.0",
"nodebb-plugin-soundpack-default": "~0.1.1",
"nodebb-plugin-spam-be-gone": "^0.4.0",
"nodebb-theme-lavender": "^0.2.0",

@ -23,6 +23,9 @@
"notif.chat.cta": "Click here to continue the conversation",
"notif.chat.unsub.info": "This chat notification was sent to you due to your subscription settings.",
"notif.post.cta": "Click here to read the full topic",
"notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.",
"test.text1": "This is a test email to verify that the emailer is set up correctly for your NodeBB.",
"unsub.cta": "Click here to alter those settings",

@ -64,6 +64,7 @@
"digest_weekly": "Weekly",
"digest_monthly": "Monthly",
"send_chat_notifications": "Send an email if a new chat message arrives and I am not online",
"send_post_notifications": "Send an email when replies are made to topics I am subscribed to",
"has_no_follower": "This user doesn't have any followers :(",
"follows_no_one": "This user isn't following anyone :(",

@ -127,32 +127,31 @@ define('forum/topic/posts', [
html.hide().fadeIn('slow');
$(window).trigger('action:posts.loaded');
onNewPostsLoaded(html, data.posts);
var pids = [];
for(var i=0; i<data.posts.length; ++i) {
pids.push(data.posts[i].pid);
}
$(window).trigger('action:posts.loaded', pids);
onNewPostsLoaded(html, pids);
callback(true);
});
}
function onNewPostsLoaded(html, posts) {
var pids = [];
for(var i=0; i<posts.length; ++i) {
pids.push(posts[i].pid);
}
function onNewPostsLoaded(html, pids) {
if (app.uid) {
socket.emit('posts.getPrivileges', pids, function(err, privileges) {
if(err) {
return app.alertError(err.message);
}
for(i=0; i<pids.length; ++i) {
for(var i=0; i<pids.length; ++i) {
toggleModTools(pids[i], privileges[i]);
}
});
} else {
for(i=0; i<pids.length; ++i) {
toggleModTools(pids[i], {editable:false, move: false});
for(var i=0; i<pids.length; ++i) {
toggleModTools(pids[i], {editable: false, move: false});
}
}

@ -19,10 +19,10 @@ var fs = require('fs'),
return Emailer;
};
Emailer.send = function(template, uid, params) {
Emailer.send = function(template, uid, params, callback) {
if (!app) {
winston.warn('[emailer] App not ready!');
return;
return callback();
}
async.parallel({
@ -36,7 +36,8 @@ var fs = require('fs'),
settings: async.apply(User.getSettings, uid)
}, function(err, results) {
if (err) {
return winston.error('[emailer] Error sending digest : ' + err.stack);
winston.error('[emailer] Error sending digest : ' + err.stack);
return callback(err);
}
async.map([results.html, results.plaintext, params.subject], function(raw, next) {
translator.translate(raw, results.settings.language || meta.config.defaultLang || 'en_GB', function(translated) {
@ -44,9 +45,11 @@ var fs = require('fs'),
});
}, function(err, translated) {
if (err) {
return winston.error(err.message);
winston.error(err.message);
return callback(err);
} else if (!results.email) {
return winston.warn('uid : ' + uid + ' has no email, not sending.');
winston.warn('uid : ' + uid + ' has no email, not sending.');
return callback();
}
if (Plugins.hasListeners('action:email.send')) {
@ -57,10 +60,12 @@ var fs = require('fs'),
html: translated[0],
plaintext: translated[1],
template: template,
uid: uid
uid: uid,
pid: params.pid
});
} else {
winston.warn('[emailer] No active email plugin found!');
callback();
}
});
});

@ -246,6 +246,10 @@ var async = require('async'),
});
};
Groups.getGroupNameByGroupSlug = function(slug, callback) {
db.getObjectField('groupslug:groupname', slug, callback);
};
Groups.getGroupFields = function(groupName, fields, callback) {
db.getObjectFields('group:' + groupName, fields, callback);
};
@ -396,7 +400,7 @@ var async = require('async'),
});
async.parallel([
async.apply(db.isObjectFields, 'groupslug:groupname', slugs),
async.apply(db.isSortedSetMember, 'groups:createtime', name)
async.apply(db.isSortedSetMembers, 'groups:createtime', name)
], function(err, results) {
if (err) {
return callback(err);

@ -347,17 +347,20 @@ SocketPosts.getUpvoters = function(socket, pids, callback) {
if (err || !Array.isArray(data) || !data.length) {
return callback(err, []);
}
var otherCount = 0;
if (data[0].length > 6) {
otherCount = data[0].length - 5;
data[0] = data[0].slice(0, 5);
}
user.getUsernamesByUids(data[0], function(err, usernames) {
callback(err, {
otherCount: otherCount,
usernames: usernames
async.map(data, function(uids, next) {
var otherCount = 0;
if (uids.length > 6) {
otherCount = uids.length - 5;
uids = uids.slice(0, 5);
}
user.getUsernamesByUids(uids, function(err, usernames) {
next(err, {
otherCount: otherCount,
usernames: usernames
});
});
});
}, callback);
});
};

@ -396,7 +396,7 @@ SocketTopics.moveAll = function(socket, data, callback) {
});
};
SocketTopics.follow = function(socket, tid, callback) {
SocketTopics.toggleFollow = function(socket, tid, callback) {
if(!socket.uid) {
return callback(new Error('[[error:not-logged-in]]'));
}
@ -404,6 +404,14 @@ SocketTopics.follow = function(socket, tid, callback) {
topics.toggleFollow(tid, socket.uid, callback);
};
SocketTopics.follow = function(socket, tid, callback) {
if(!socket.uid) {
return callback(new Error('[[error:not-logged-in]]'));
}
topics.follow(tid, socket.uid, callback);
};
SocketTopics.loadMore = function(socket, data, callback) {
if(!data || !data.tid || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback(new Error('[[error:invalid-data]]'));

@ -4,12 +4,15 @@
var async = require('async'),
nconf = require('nconf'),
S = require('string'),
winston = require('winston'),
db = require('../database'),
user = require('../user'),
posts = require('../posts'),
postTools = require('../postTools'),
notifications = require('../notifications');
notifications = require('../notifications'),
meta = require('../meta'),
emailer = require('../emailer');
module.exports = function(Topics) {
@ -125,6 +128,28 @@ module.exports = function(Topics) {
notifications.push(notification, followers);
}
});
async.eachLimit(followers, 3, function(toUid, next) {
async.parallel({
userData: async.apply(user.getUserFields, toUid, ['username']),
userSettings: async.apply(user.getSettings, toUid)
}, function(err, data) {
if (data.userSettings.hasOwnProperty('sendPostNotifications') && data.userSettings.sendPostNotifications) {
emailer.send('notif_post', toUid, {
pid: postData.pid,
subject: '[' + (meta.config.title || 'NodeBB') + '] ' + title,
intro: '[[notifications:user_posted_to, ' + postData.user.username + ', ' + title + ']]',
postBody: postData.content,
site_title: meta.config.title || 'NodeBB',
username: data.userData.username,
url: nconf.get('url') + '/topics/' + postData.topic.tid,
base_url: nconf.get('url')
}, next);
} else {
winston.debug('[topics.notifyFollowers] uid ' + toUid + ' does not have post notifications enabled, skipping.');
}
});
});
});
};
};

@ -69,6 +69,7 @@ module.exports = function(User) {
settings.followTopicsOnCreate = (settings.followTopicsOnCreate === null || settings.followTopicsOnCreate === undefined) ? true : parseInt(settings.followTopicsOnCreate, 10) === 1;
settings.followTopicsOnReply = parseInt(settings.followTopicsOnReply, 10) === 1;
settings.sendChatNotifications = parseInt(settings.sendChatNotifications, 10) === 1;
settings.sendPostNotifications = parseInt(settings.sendPostNotifications, 10) === 1;
settings.restrictChat = parseInt(settings.restrictChat, 10) === 1;
settings.topicSearchEnabled = parseInt(settings.topicSearchEnabled, 10) === 1;

@ -0,0 +1,16 @@
<p>[[email:greeting_with_name, {username}]],</p>
<p>{intro}:</p>
<blockquote>{postBody}</blockquote>
<a href="{url}">[[email:notif.post.cta]]</a>
<p>
[[email:closing]]<br />
<strong>{site_title}</strong>
</p>
<hr />
<p>
[[email:notif.post.unsub.info]] <a href="{base_url}/user/{username}/settings">[[email:unsub.cta]]</a>.
</p>

@ -0,0 +1,14 @@
[[email:greeting_with_name, {username}]],
{intro}:
{postBody}
[[email:notif.post.cta]]: {url}
[[email:closing]]
{site_title}
===
[[email:notif.post.unsub.info]] <a href="{base_url}/user/{username}/settings">[[email:unsub.cta]]</a>.
Loading…
Cancel
Save