From 74ceb78800a2052c4ec7fea6bcae90e432119a78 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Tue, 21 Nov 2017 12:14:14 -0700
Subject: [PATCH] Upvote notification frequency selection (#6087)
Closes #5963
- Notify on every upvote
- Notify on every tenth upvote
- Notify logarithmically (on 10, 100, 1000...)
- Disable upvote notifications
---
public/language/en-GB/user.json | 5 +++
src/controllers/accounts/settings.js | 14 ++++++++
src/posts/votes.js | 1 +
src/socket.io/helpers.js | 49 ++++++++++++++++++++++++++--
src/socket.io/posts/helpers.js | 4 ++-
src/user/settings.js | 4 +--
6 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/public/language/en-GB/user.json b/public/language/en-GB/user.json
index a5bbf4d1ff..a3be8c30b4 100644
--- a/public/language/en-GB/user.json
+++ b/public/language/en-GB/user.json
@@ -110,6 +110,11 @@
"outgoing-message-sound": "Outgoing message sound",
"notification-sound": "Notification sound",
"no-sound": "No sound",
+ "upvote-notif-freq": "Upvote Notification Frequency",
+ "upvote-notif-freq.all": "All Upvotes",
+ "upvote-notif-freq.everyTen": "Every Ten Upvotes",
+ "upvote-notif-freq.logarithmic": "On 10, 100, 1000...",
+ "upvote-notif-freq.disabled": "Disabled",
"browsing": "Browsing Settings",
"open_links_in_new_tab": "Open outgoing links in new tab",
diff --git a/src/controllers/accounts/settings.js b/src/controllers/accounts/settings.js
index ea9c10126b..0bb3ef1744 100644
--- a/src/controllers/accounts/settings.js
+++ b/src/controllers/accounts/settings.js
@@ -135,6 +135,20 @@ settingsController.get = function (req, res, callback) {
language.selected = language.code === userData.settings.userLang;
});
+ var notifFreqOptions = [
+ 'all',
+ 'everyTen',
+ 'logarithmic',
+ 'disabled',
+ ];
+
+ userData.upvoteNotifFreq = notifFreqOptions.map(function (name) {
+ return {
+ name: name,
+ selected: name === userData.notifFreqOptions,
+ };
+ });
+
userData.disableCustomUserSkins = parseInt(meta.config.disableCustomUserSkins, 10) === 1;
userData.allowUserHomePage = parseInt(meta.config.allowUserHomePage, 10) === 1;
diff --git a/src/posts/votes.js b/src/posts/votes.js
index 5598be9b24..e37cbff017 100644
--- a/src/posts/votes.js
+++ b/src/posts/votes.js
@@ -232,6 +232,7 @@ module.exports = function (Posts) {
user: {
reputation: newreputation,
},
+ fromuid: uid,
post: postData,
upvote: type === 'upvote' && !unvote,
downvote: type === 'downvote' && !unvote,
diff --git a/src/socket.io/helpers.js b/src/socket.io/helpers.js
index cbc01aff60..ae4c2b0b5a 100644
--- a/src/socket.io/helpers.js
+++ b/src/socket.io/helpers.js
@@ -13,7 +13,7 @@ var notifications = require('../notifications');
var plugins = require('../plugins');
var utils = require('../utils');
-var SocketHelpers = {};
+var SocketHelpers = module.exports;
SocketHelpers.notifyOnlineUsers = function (uid, result) {
winston.warn('[deprecated] SocketHelpers.notifyOnlineUsers, consider using socketHelpers.notifyNew(uid, \'newPost\', result);');
@@ -171,6 +171,51 @@ SocketHelpers.sendNotificationToTopicOwner = function (tid, fromuid, command, no
});
};
+SocketHelpers.upvote = function (data, notification) {
+ if (!data || !data.post || !data.post.uid || !data.post.votes || !data.post.pid || !data.fromuid) {
+ return;
+ }
+
+ var votes = data.post.votes;
+ var touid = data.post.uid;
+ var fromuid = data.fromuid;
+ var pid = data.post.pid;
+
+ var shouldNotify = {
+ all: function () {
+ return votes > 0;
+ },
+ everyTen: function () {
+ return votes > 0 && votes % 10 === 0;
+ },
+ logarithmic: function () {
+ return votes > 1 && Math.log10(votes) % 1 === 0;
+ },
+ disabled: function () {
+ return false;
+ },
+ };
+
+ async.waterfall([
+ function (next) {
+ user.getSettings(touid, next);
+ },
+ function (settings, next) {
+ var should = shouldNotify[settings.upvoteNotifFreq] || shouldNotify.all;
+
+ if (should()) {
+ SocketHelpers.sendNotificationToPostOwner(pid, fromuid, 'upvote', notification);
+ }
+
+ next();
+ },
+ ], function (err) {
+ if (err) {
+ winston.error(err);
+ }
+ });
+};
+
SocketHelpers.rescindUpvoteNotification = function (pid, fromuid) {
var uid;
async.waterfall([
@@ -199,5 +244,3 @@ SocketHelpers.emitToTopicAndCategory = function (event, data) {
websockets.in('topic_' + data.tid).emit(event, data);
websockets.in('category_' + data.cid).emit(event, data);
};
-
-module.exports = SocketHelpers;
diff --git a/src/socket.io/posts/helpers.js b/src/socket.io/posts/helpers.js
index a9bb9b451d..a4438ba981 100644
--- a/src/socket.io/posts/helpers.js
+++ b/src/socket.io/posts/helpers.js
@@ -69,7 +69,9 @@ function executeCommand(socket, command, eventName, notification, data, callback
websockets.in(data.room_id).emit('event:' + eventName, result);
}
- if (result && notification) {
+ if (result && command === 'upvote') {
+ socketHelpers.upvote(result, notification);
+ } else if (result && notification) {
socketHelpers.sendNotificationToPostOwner(data.pid, socket.uid, command, notification);
} else if (result && command === 'unvote') {
socketHelpers.rescindUpvoteNotification(data.pid, socket.uid);
diff --git a/src/user/settings.js b/src/user/settings.js
index 784213e603..df22ff5c42 100644
--- a/src/user/settings.js
+++ b/src/user/settings.js
@@ -74,8 +74,7 @@ module.exports = function (User) {
settings.categoryTopicSort = getSetting(settings, 'categoryTopicSort', 'newest_to_oldest');
settings.followTopicsOnCreate = parseInt(getSetting(settings, 'followTopicsOnCreate', 1), 10) === 1;
settings.followTopicsOnReply = parseInt(getSetting(settings, 'followTopicsOnReply', 0), 10) === 1;
- settings.sendChatNotifications = parseInt(getSetting(settings, 'sendChatNotifications', 0), 10) === 1;
- settings.sendPostNotifications = parseInt(getSetting(settings, 'sendPostNotifications', 0), 10) === 1;
+ settings.upvoteNotifFreq = getSetting(settings, 'upvoteNotifFreq', 'all');
settings.restrictChat = parseInt(getSetting(settings, 'restrictChat', 0), 10) === 1;
settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1;
settings.delayImageLoading = parseInt(getSetting(settings, 'delayImageLoading', 1), 10) === 1;
@@ -131,6 +130,7 @@ module.exports = function (User) {
notificationSound: data.notificationSound,
incomingChatSound: data.incomingChatSound,
outgoingChatSound: data.outgoingChatSound,
+ upvoteNotifFreq: data.upvoteNotifFreq,
notificationType_upvote: data.notificationType_upvote,
'notificationType_new-topic': data['notificationType_new-topic'],
'notificationType_new-reply': data['notificationType_new-reply'],