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'],