diff --git a/mocks/databasemock.js b/mocks/databasemock.js
index a75a1e89a1..3b99f075ff 100644
--- a/mocks/databasemock.js
+++ b/mocks/databasemock.js
@@ -79,7 +79,7 @@
}
winston.info('test_database flushed');
- /*
+
meta.configs.init(function () {
nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-vanilla/templates'));
@@ -90,8 +90,7 @@
sockets.init(webserver.server);
done();
- });*/
- done();
+ });
});
});
});
diff --git a/package.json b/package.json
index 25eed44af8..42015d4afe 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"scripts": {
"start": "./nodebb start",
"stop": "./nodebb stop",
- "test": "mocha ./tests/database.js -t 1000"
+ "test": "mocha ./tests -t 10000"
},
"dependencies": {
"express": "3.2.0",
diff --git a/public/language/en_GB/global.json b/public/language/en_GB/global.json
index c935f1c5d8..de15a7e4ce 100644
--- a/public/language/en_GB/global.json
+++ b/public/language/en_GB/global.json
@@ -69,6 +69,6 @@
"invisible": "Invisible",
"offline": "Offline",
- "privacy": "Privacy",
+ "email": "Email",
"language": "Language"
}
diff --git a/public/language/en_GB/notifications.json b/public/language/en_GB/notifications.json
index 748c89bfb7..d480d39a2e 100644
--- a/public/language/en_GB/notifications.json
+++ b/public/language/en_GB/notifications.json
@@ -9,5 +9,13 @@
"continue_to": "Continue to",
"return_to": "Return to ",
"new_notification": "New Notification",
- "you_have_unread_notifications": "You have unread notifications."
+ "you_have_unread_notifications": "You have unread notifications.",
+
+ "user_made_post": "%1 made a new post",
+ "new_message_from": "New message from %1",
+ "upvoted_your_post": "%1 has upvoted your post.",
+ "favourited_your_post": "%1 has favourited your post.",
+ "user_flagged_post": "%1 flagged a post.",
+ "user_posted_to" : "%1 has posted a reply to: %2"
+
}
diff --git a/public/language/en_GB/user.json b/public/language/en_GB/user.json
index 1ca6651efb..a9a384da43 100644
--- a/public/language/en_GB/user.json
+++ b/public/language/en_GB/user.json
@@ -47,6 +47,12 @@
"settings": "Settings",
"show_email": "Show My Email",
+ "digest_label": "Subscribe to Digest",
+ "digest_description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule",
+ "digest_off": "Off",
+ "digest_daily": "Daily",
+ "digest_weekly": "Weekly",
+ "digest_monthly": "Monthly",
"has_no_follower": "This user doesn't have any followers :(",
"follows_no_one": "This user isn't following anyone :(",
diff --git a/public/src/forum/accountsettings.js b/public/src/forum/accountsettings.js
index bb18cacb2c..4945eb8abb 100644
--- a/public/src/forum/accountsettings.js
+++ b/public/src/forum/accountsettings.js
@@ -16,11 +16,11 @@ define(['forum/accountheader'], function(header) {
}
switch (input.attr('type')) {
- case 'text' :
- case 'textarea' :
+ case 'text':
+ case 'textarea':
settings[setting] = input.val();
break;
- case 'checkbox' :
+ case 'checkbox':
settings[setting] = input.is(':checked') ? 1 : 0;
break;
}
diff --git a/public/src/forum/admin/plugins.js b/public/src/forum/admin/plugins.js
index a494f3053d..01b4e4589f 100644
--- a/public/src/forum/admin/plugins.js
+++ b/public/src/forum/admin/plugins.js
@@ -1,3 +1,6 @@
+"use strict";
+/* global define, app, socket */
+
define(function() {
var Plugins = {
init: function() {
@@ -19,10 +22,13 @@ define(function() {
app.alert({
alert_id: 'plugin_toggled',
title: 'Plugin ' + (status.active ? 'Enabled' : 'Disabled'),
- message: 'Restarting your NodeBB ',
- type: 'warning',
- timeout: 5000
- })
+ message: 'Please restart your NodeBB to fully ' + (status.active ? 'activate' : 'deactivate') + ' this plugin',
+ type: 'info',
+ timeout: 5000,
+ clickfn: function() {
+ socket.emit('admin.restart');
+ }
+ });
});
} else {
pluginsList.append('
No plugins found.
');
diff --git a/public/src/forum/admin/themes.js b/public/src/forum/admin/themes.js
index 4dd38c1d92..e74887d8f2 100644
--- a/public/src/forum/admin/themes.js
+++ b/public/src/forum/admin/themes.js
@@ -39,10 +39,13 @@ define(['forum/admin/settings'], function(Settings) {
app.alert({
alert_id: 'admin:theme',
- type: 'success',
+ type: 'info',
title: 'Theme Changed',
- message: 'Restarting your NodeBB ',
- timeout: 3500
+ message: 'Please restart your NodeBB to fully activate this theme',
+ timeout: 5000,
+ clickfn: function() {
+ socket.emit('admin.restart');
+ }
});
});
}
@@ -251,7 +254,7 @@ define(['forum/admin/settings'], function(Settings) {
timeout: 2500
});
}
-
+
});
});
}
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
index adb5bc34c7..8acd9543ce 100644
--- a/public/src/forum/category.js
+++ b/public/src/forum/category.js
@@ -225,11 +225,13 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
});
}
- Category.onTopicsLoaded = function(topics, callback) {
- if(!topics || !topics.length) {
+ Category.onTopicsLoaded = function(data, callback) {
+ if(!data || !data.topics.length) {
return;
}
+ var topics = data.topics;
+
function removeAlreadyAddedTopics() {
topics = topics.filter(function(topic) {
return $('#topics-container li[data-tid="' + topic.tid +'"]').length === 0;
@@ -261,7 +263,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
findInsertionPoint();
ajaxify.loadTemplate('category', function(categoryTemplate) {
- var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), {topics: topics});
+ var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), data);
translator.translate(html, function(translatedHTML) {
var container = $('#topics-container'),
@@ -309,6 +311,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
cid: cid,
after: after
}, function (err, data) {
+ console.log(data);
loadingMoreTopics = false;
if(err) {
@@ -316,7 +319,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
}
if (data && data.topics.length) {
- Category.onTopicsLoaded(data.topics, callback);
+ Category.onTopicsLoaded(data, callback);
$('#topics-container').attr('data-nextstart', data.nextStart);
} else {
diff --git a/public/src/modules/notifications.js b/public/src/modules/notifications.js
index 9987a5cedd..2d4120b903 100644
--- a/public/src/modules/notifications.js
+++ b/public/src/modules/notifications.js
@@ -1,3 +1,8 @@
+'use strict';
+
+/* globals define, socket, translator, utils, config, app, ajaxify, Tinycon*/
+
+
define(['sounds'], function(sound) {
var Notifications = {};
@@ -13,50 +18,44 @@ define(['sounds'], function(sound) {
socket.emit('notifications.get', null, function(err, data) {
- var numRead = data.read.length,
- numUnread = data.unread.length,
- x;
+ function createNotification(notification, callback) {
+ if (notification.image) {
+ image = '';
+ } else {
+ image = '';
+ }
+
+ return '' + image + '' + utils.relativeTime(notification.datetime, true) + '' + notification.text + '';
+ }
- var html = '';
+ var x, html = '';
if (!err && (data.read.length + data.unread.length) > 0) {
var image = '';
- for (x = 0; x < numUnread; x++) {
- if (data.unread[x].image) {
- image = '';
- } else {
- image = '';
- }
- html += '' + image + '' + utils.relativeTime(data.unread[x].datetime, true) + '' + data.unread[x].text + '';
+ for (x = 0; x < data.unread.length; x++) {
+ html += createNotification(data.unread[x]);
}
- for (x = 0; x < numRead; x++) {
- if (data.read[x].image) {
- image = '';
- } else {
- image = '';
- }
- html += '' + image + '' + utils.relativeTime(data.read[x].datetime, true) + '' + data.read[x].text + '';
+ for (x = 0; x < data.read.length; x++) {
+ html += createNotification(data.read[x]);
}
- addSeeAllLink(replaceHtml);
+
+ addSeeAllLink();
} else {
- translator.translate('[[notifications:no_notifs]]', function(translated) {
- html += translated;
- addSeeAllLink(replaceHtml);
- });
+ html += '[[notifications:no_notifs]]';
+ addSeeAllLink();
}
- function addSeeAllLink(callback) {
- translator.translate('[[notifications:see_all]]', function(translated) {
- html += translated;
- callback();
- });
+ function addSeeAllLink() {
+ html += '[[notifications:see_all]]';
}
- function replaceHtml() {
- notifList.html(html);
- }
+
+ translator.translate(html, function(translated) {
+ notifList.html(translated);
+ });
+
updateNotifCount(data.unread.length);
diff --git a/src/categoryTools.js b/src/categoryTools.js
index d07f5007de..cfbe00d53f 100644
--- a/src/categoryTools.js
+++ b/src/categoryTools.js
@@ -2,6 +2,7 @@
var Groups = require('./groups'),
User = require('./user'),
+ categories = require('./categories'),
async = require('async'),
db = require('./database');
@@ -36,6 +37,9 @@ CategoryTools.exists = function(cid, callback) {
CategoryTools.privileges = function(cid, uid, callback) {
async.parallel({
+ "disabled": function(next) {
+ categories.getCategoryField(cid, 'disabled', next);
+ },
"+r": function(next) {
internals.isMember('cid:' + cid + ':privileges:+r', uid, next);
},
@@ -62,6 +66,7 @@ CategoryTools.privileges = function(cid, uid, callback) {
"g+w": privileges['g+w'],
read: (
(
+ parseInt(privileges.disabled, 10) !== 1 &&
(privileges['+r'] || privileges['+r'] === null) &&
(privileges['g+r'] || privileges['g+r'] === null)
) ||
@@ -70,6 +75,7 @@ CategoryTools.privileges = function(cid, uid, callback) {
),
write: (
(
+ parseInt(privileges.disabled, 10) !== 1 &&
(privileges['+w'] || privileges['+w'] === null) &&
(privileges['g+w'] || privileges['g+w'] === null)
) ||
diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js
index 97678b4963..0eab10a25f 100644
--- a/src/controllers/accounts.js
+++ b/src/controllers/accounts.js
@@ -348,9 +348,15 @@ accountsController.accountSettings = function(req, res, next) {
return userNotFound();
}
- results.user.yourid = req.user.uid;
- results.user.theirid = uid;
- results.user.settings = settings;
+ results = {
+ username: results.user.username,
+ userslug: results.user.userslug,
+ uid: uid,
+ yourid: req.user.uid,
+ theirid: uid,
+ settings: settings,
+ languages: results.languages
+ };
res.render('accountsettings', results);
});
diff --git a/src/controllers/admin.js b/src/controllers/admin.js
index 41e8618344..953a06291f 100644
--- a/src/controllers/admin.js
+++ b/src/controllers/admin.js
@@ -37,7 +37,8 @@ adminController.home = function(req, res, next) {
res.render('admin/index', {
version: pkg.version,
emailerInstalled: plugins.hasListeners('action:email.send'),
- searchInstalled: plugins.hasListeners('filter:search.query')
+ searchInstalled: plugins.hasListeners('filter:search.query'),
+ restartRequired: meta.restartRequired
});
};
diff --git a/src/controllers/categories.js b/src/controllers/categories.js
index f30dcc13b3..07f6bf9ab0 100644
--- a/src/controllers/categories.js
+++ b/src/controllers/categories.js
@@ -68,14 +68,14 @@ categoriesController.get = function(req, res, next) {
async.waterfall([
function(next) {
categoryTools.privileges(cid, uid, function(err, categoryPrivileges) {
- if (!err) {
- if (!categoryPrivileges.read) {
- next(new Error('[[error:no-privileges]]'));
- } else {
- next(null, categoryPrivileges);
- }
+ if (err) {
+ return next(err);
+ }
+
+ if (!categoryPrivileges.read) {
+ next(new Error('[[error:no-privileges]]'));
} else {
- next(err);
+ next(null, categoryPrivileges);
}
});
},
diff --git a/src/meta.js b/src/meta.js
index 6837619cfe..26f84262df 100644
--- a/src/meta.js
+++ b/src/meta.js
@@ -18,7 +18,9 @@ var fs = require('fs'),
User = require('./user');
(function (Meta) {
+ Meta.restartRequired = false;
Meta.config = {};
+
Meta.configs = {
init: function (callback) {
delete Meta.config;
@@ -159,6 +161,9 @@ var fs = require('fs'),
db.setObjectField('config', 'theme:src', data.src, callback);
break;
}
+
+ // Restart Required flag
+ meta.restartRequired = true;
}
};
diff --git a/src/plugins.js b/src/plugins.js
index 16e421ce62..4d56fd94d4 100644
--- a/src/plugins.js
+++ b/src/plugins.js
@@ -383,6 +383,8 @@ var fs = require('fs'),
return;
}
+ // Restart Required flag
+ meta.restartRequired = true;
if(active) {
Plugins.fireHook('action:plugin.deactivate', id);
diff --git a/src/routes/debug.js b/src/routes/debug.js
index 6c03961251..ca7a13b665 100644
--- a/src/routes/debug.js
+++ b/src/routes/debug.js
@@ -54,7 +54,6 @@ module.exports = function(app, middleware, controllers) {
});
app.get('/test', function(req, res) {
- require('../meta').sounds.init();
res.send(200);
});
});
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js
index 64fbb841ba..05286f616b 100644
--- a/src/socket.io/admin.js
+++ b/src/socket.io/admin.js
@@ -79,7 +79,6 @@ SocketAdmin.themes.set = function(socket, data, callback) {
widgets.reset(function(err) {
meta.themes.set(data, function() {
callback();
- meta.restart();
});
});
};
@@ -87,7 +86,6 @@ SocketAdmin.themes.set = function(socket, data, callback) {
SocketAdmin.plugins.toggle = function(socket, plugin_id) {
plugins.toggleActive(plugin_id, function(status) {
socket.emit('admin.plugins.toggle', status);
- meta.restart();
});
};
diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js
index 80af126f29..3687424bd5 100644
--- a/src/socket.io/categories.js
+++ b/src/socket.io/categories.js
@@ -1,6 +1,7 @@
'use strict';
-var categories = require('../categories'),
+var async = require('async'),
+ categories = require('../categories'),
categoryTools = require('../categoryTools'),
meta = require('./../meta'),
user = require('./../user'),
@@ -30,12 +31,29 @@ SocketCategories.loadMore = function(socket, data, callback) {
return callback(new Error('[[error:invalid-data]]'));
}
- user.getSettings(socket.uid, function(err, settings) {
+ async.parallel({
+ privileges: function(next) {
+ categoryTools.privileges(data.cid, socket.uid, next);
+ },
+ settings: function(next) {
+ user.getSettings(socket.uid, next);
+ }
+ }, function(err, results) {
+ if (err) {
+ return callback(err);
+ }
var start = parseInt(data.after, 10),
- end = start + settings.topicsPerPage - 1;
+ end = start + results.settings.topicsPerPage - 1;
+
+ categories.getCategoryTopics(data.cid, start, end, socket.uid, function(err, data) {
+ if (err) {
+ return callback(err);
+ }
- categories.getCategoryTopics(data.cid, start, end, socket.uid, callback);
+ data.privileges = results.privileges;
+ callback(null, data);
+ });
});
};
diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js
index 401d09a8e9..9d8d233c64 100644
--- a/src/socket.io/modules.js
+++ b/src/socket.io/modules.js
@@ -194,7 +194,7 @@ SocketModules.chats.send = function(socket, data, callback) {
function sendChatNotification(fromuid, touid, username) {
if (!module.parent.exports.isUserOnline(touid)) {
- var notifText = 'New message from ' + username + '';
+ var notifText = '[[notifications:new_message_from,' + username + ']]';
notifications.create({
text: notifText,
path: 'javascript:app.openChat('' + username + '', ' + fromuid + ');',
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index f2144896cd..dde786af7e 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -33,14 +33,11 @@ SocketPosts.reply = function(socket, data, callback) {
}
if (postData) {
-
- module.parent.exports.emitTopicPostStats();
-
- var socketData = {
+ websockets.server.sockets.emit('event:new_post', {
posts: [postData]
- };
+ });
- websockets.server.sockets.emit('event:new_post', socketData);
+ module.parent.exports.emitTopicPostStats();
callback();
}
@@ -49,7 +46,7 @@ SocketPosts.reply = function(socket, data, callback) {
SocketPosts.upvote = function(socket, data, callback) {
favouriteCommand('upvote', 'voted', socket, data, callback);
- sendNotificationToPostOwner(data, socket.uid, 'has upvoted your post');
+ sendNotificationToPostOwner(data, socket.uid, 'notifications:upvoted_your_post');
};
SocketPosts.downvote = function(socket, data, callback) {
@@ -62,7 +59,7 @@ SocketPosts.unvote = function(socket, data, callback) {
SocketPosts.favourite = function(socket, data, callback) {
favouriteCommand('favourite', 'favourited', socket, data, callback);
- sendNotificationToPostOwner(data, socket.uid, 'has favourited your post');
+ sendNotificationToPostOwner(data, socket.uid, 'notifications:favourited_your_post');
};
SocketPosts.unfavourite = function(socket, data, callback) {
@@ -87,7 +84,7 @@ function favouriteCommand(command, eventName, socket, data, callback) {
}
}
-function sendNotificationToPostOwner(data, uid, message) {
+function sendNotificationToPostOwner(data, uid, notification) {
if(data && data.pid && uid) {
posts.getPostFields(data.pid, ['tid', 'uid'], function(err, postData) {
if (err) {
@@ -109,8 +106,9 @@ function sendNotificationToPostOwner(data, uid, message) {
if (err) {
return;
}
+
notifications.create({
- text: '' + results.username + ' ' + message,
+ text: '[[' + notification + ', ' + results.username + ']]',
path: nconf.get('relative_path') + '/topic/' + results.slug + '#' + data.pid,
uniqueId: 'post:' + data.pid,
from: uid
@@ -258,7 +256,7 @@ SocketPosts.flag = function(socket, pid, callback) {
user.getUserField(socket.uid, 'username', next);
},
function(username, next) {
- message = '' + username + ' flagged a post.';
+ message = '[[notifications:user_flagged_post, ' + username + ']]';
posts.getPostField(pid, 'tid', next);
},
function(tid, next) {
diff --git a/src/threadTools.js b/src/threadTools.js
index 565bf93ec6..d2de95bb3f 100644
--- a/src/threadTools.js
+++ b/src/threadTools.js
@@ -229,7 +229,7 @@ var winston = require('winston'),
}
notifications.create({
- text: '' + username + ' has posted a reply to: "' + topicData.title + '"',
+ text: '[[notifications:user_posted_to, ' + username + ', ' + topicData.title + ']]',
path: nconf.get('relative_path') + '/topic/' + topicData.slug + '#' + pid,
uniqueId: 'topic:' + tid,
from: exceptUid
diff --git a/src/user/create.js b/src/user/create.js
index 87c90e4076..37cff32d72 100644
--- a/src/user/create.js
+++ b/src/user/create.js
@@ -49,7 +49,6 @@ module.exports = function(User) {
}
if (exists) {
async.forever(function(next) {
- // Append a random number to the username
var newUsername = userData.username + (Math.floor(Math.random() * 255) + 1);
User.exists(newUsername, function(err, exists) {
if (!exists) {
@@ -87,10 +86,11 @@ module.exports = function(User) {
if (err) {
return callback(err);
}
- userData = results[results.length - 1];
+ userData = results[results.length - 1];
+ var userNameChanged = !!results[3];
// If a new username was picked...
- if (results[3]) {
+ if (userNameChanged) {
userData.username = results[3];
userData.userslug = utils.slugify(results[3]);
}
@@ -149,16 +149,13 @@ module.exports = function(User) {
groups.join('registered-users', uid);
- // If their username was automatically changed...
- if (results[3]) {
- translator.translate('[[user:username_taken_workaround, ' + userData.username + ']]', function(notifText) {
- notifications.create({
- text: notifText,
- picture: 'brand:logo',
- datetime: Date.now()
- }, function(nid) {
- notifications.push(nid, uid);
- });
+ if (userNameChanged) {
+ notifications.create({
+ text: '[[user:username_taken_workaround, ' + userData.username + ']]',
+ picture: 'brand:logo',
+ datetime: Date.now()
+ }, function(nid) {
+ notifications.push(nid, uid);
});
}
diff --git a/src/user/jobs.js b/src/user/jobs.js
index 602b889039..c2e88e752f 100644
--- a/src/user/jobs.js
+++ b/src/user/jobs.js
@@ -8,7 +8,6 @@ var db = require('../database'),
nconf = require('nconf'),
user = require('../user'),
- UserNotifications = require('./notifications'),
topics = require('../topics'),
emailer = require('../emailer'),
meta = require('../meta');
@@ -23,6 +22,8 @@ module.exports = function(User) {
};
User.sendDailyDigests = function() {
+ var yesterday = Date.now() - (1000*60*60*24);
+
async.parallel({
recent: function(next) {
topics.getLatestTopics(0, 0, 10, 'day', next);
@@ -33,39 +34,61 @@ module.exports = function(User) {
}, function(err, data) {
var now = new Date();
- async.each(data.uids, function(uid, next) {
- UserNotifications.getDailyUnread(uid, function(err, notifications) {
- if (!err && notifications && notifications.length) {
+ async.parallel({
+ recipients: function(next) {
+ User.getMultipleUserFields(data.uids, ['uid', 'username', 'lastonline'], next);
+ },
+ userSettings: function(next) {
+ User.getMultipleUserSettings(data.uids, next);
+ }
+ }, function(err, users) {
+ var recipients = users.recipients,
+ userSettings = users.userSettings,
+ subscribed;
+ // Find uids subscribed to daily digest emails
+ subscribed = userSettings.filter(function(setting) {
+ return !setting.dailyDigestFreq || setting.dailyDigestFreq === 'daily';
+ }).map(function(setting) {
+ return setting.uid;
+ });
+
+ // Find only those users who have not been online in the past 24 hours
+ var users = recipients.filter(function(userObj) {
+ return subscribed.indexOf(userObj.uid) !== -1 && yesterday > parseInt(userObj.lastonline, 10);
+ });
+
+ // Consider using eachLimit, but *only* if people complain about email relays choking -- otherwise we're ok.
+ async.each(users, function(userObj, next) {
+ user.notifications.getDailyUnread(userObj.uid, function(err, notifications) {
+ // Turn relative URLs into absolute ones
for(var i=0; i made a new post';
+ var message = '[[notifications:user_made_post, ' + username + ']]';
notifications.create({
text: message,
diff --git a/src/user/settings.js b/src/user/settings.js
index ab80e4fb42..781b1934f5 100644
--- a/src/user/settings.js
+++ b/src/user/settings.js
@@ -25,6 +25,7 @@ module.exports = function(User) {
settings = data.settings;
settings.showemail = settings.showemail ? parseInt(settings.showemail, 10) !== 0 : false;
+ settings.dailyDigestFreq = settings.dailyDigestFreq || 'daily';
settings.usePagination = settings.usePagination ? parseInt(settings.usePagination, 10) === 1 : parseInt(meta.config.usePagination, 10) === 1;
settings.topicsPerPage = settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : parseInt(meta.config.topicsPerPage, 10) || 20;
settings.postsPerPage = settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : parseInt(meta.config.postsPerPage, 10) || 10;
@@ -35,16 +36,43 @@ module.exports = function(User) {
});
};
+ User.getMultipleUserSettings = function(uids, callback) {
+ if (!Array.isArray(uids) || !uids.length) {
+ return callback(null, []);
+ }
+
+ var keys = uids.map(function(uid) {
+ return 'user:' + uid + ':settings';
+ });
+
+ db.getObjects(keys, function(err, settings) {
+ if (err) {
+ return callback(err);
+ }
+
+ // Associate uid
+ settings = settings.map(function(setting, idx) {
+ setting = setting || {};
+ setting.uid = uids[idx];
+ return setting;
+ });
+
+ callback(null, settings);
+ });
+ };
+
User.saveSettings = function(uid, data, callback) {
if(!data.topicsPerPage || !data.postsPerPage || parseInt(data.topicsPerPage, 10) <= 0 || parseInt(data.postsPerPage, 10) <= 0) {
return callback(new Error('[[error:invalid-pagination-value]]'));
}
- plugins.fireHook('action:user.saveSettings', {uid: uid, settings: data});
+ data.language = data.language || meta.config.defaultLang;
+ plugins.fireHook('action:user.saveSettings', {uid: uid, settings: data});
db.setObject('user:' + uid + ':settings', {
showemail: data.showemail,
+ dailyDigestFreq: data.dailyDigestFreq || 'daily',
usePagination: data.usePagination,
topicsPerPage: data.topicsPerPage,
postsPerPage: data.postsPerPage,