diff --git a/README.md b/README.md index 37df801..4a28779 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ Currently supported settings: maxvotes="1" //Max number of votes per user. If larger than 1, a multiple choice poll will be created disallowVoteUpdate="0" //if set, users won't be able to update/remove their vote title="Poll title" //Poll title + privateVotes="true" //if set, only the poll creator and admins can see per user voting details + hiddenVotes="true" //if set, only admins can see per user voting details (overrides privateVotes) There's also a helpful modal available that will allow you to easily create a poll: ![](https://i.imgur.com/2fPnWLb.png) diff --git a/languages/en_GB/poll.json b/languages/en_GB/poll.json index d81c3ef..208024f 100755 --- a/languages/en_GB/poll.json +++ b/languages/en_GB/poll.json @@ -8,6 +8,8 @@ "default_title": "Default poll title", "max_votes": "Maximum number of votes per user", "disallow_vote_update": "Don't allow users to update their vote", + "private_votes": "Private votes", + "hidden_votes": "Hidden votes", "info_choices": "A number greater than 1 will enable multiple choice polls.", "settings": "Settings", "save": "Save", @@ -41,8 +43,10 @@ "voting_unavailable_message": "This poll has ended or has been marked as deleted. You can still view the results.", "voting_update_disallowed_message": "You have already voted and changing your vote is not allowed for this poll", "vote_is_final": "Changing your vote is not allowed for this poll so your vote is final", + "votes_are_private": "The votes in this poll are hidden from other users excluding the creator of the poll.", + "votes_are_hidden": "The votes in this poll are hidden from other users.", "vote_count": "users voted for this option", "votes": "votes", "admin.create-poll": "Create Poll" -} \ No newline at end of file +} diff --git a/languages/en_US/poll.json b/languages/en_US/poll.json index b324b70..2525caa 100755 --- a/languages/en_US/poll.json +++ b/languages/en_US/poll.json @@ -8,6 +8,8 @@ "default_title": "Default poll title", "max_votes": "Maximum number of votes per user", "disallow_vote_update": "Don't allow users to update their vote", + "private_votes": "Private votes", + "hidden_votes": "Hidden votes", "info_choices": "A number greater than 1 will enable multiple choice polls.", "settings": "Settings", "save": "Save", @@ -41,7 +43,9 @@ "voting_unavailable_message": "This poll has ended or has been marked as deleted. You can still view the results.", "voting_update_disallowed_message": "You have already voted and changing your vote is not allowed for this poll", "vote_is_final": "Changing your vote is not allowed for this poll so your vote is final", + "votes_are_private": "The votes in this poll are hidden from other users excluding the creator of the poll.", + "votes_are_hidden": "The votes in this poll are hidden from other users.", "vote_count": "users voted for this option", "votes": "votes" -} \ No newline at end of file +} diff --git a/lib/config.js b/lib/config.js index 43a44e3..9c9f255 100755 --- a/lib/config.js +++ b/lib/config.js @@ -28,6 +28,8 @@ const pluginId = pluginInfo.id.replace('nodebb-plugin-', ''); maxvotes: 1, disallowVoteUpdate: 0, end: 0, + privateVotes: 0, + hiddenVotes: 0, }, }; @@ -45,4 +47,4 @@ const pluginId = pluginInfo.id.replace('nodebb-plugin-', ''); callback(null, Config.settings.createDefaultWrapper()); }, }; -}(exports)); +}(exports)); \ No newline at end of file diff --git a/lib/poll.js b/lib/poll.js index 2d7e012..5c5c181 100755 --- a/lib/poll.js +++ b/lib/poll.js @@ -93,6 +93,8 @@ const Scheduler = require('./scheduler'); option.percentage = isNaN(percentage) ? 0 : percentage; }); pollData.settings.disallowVoteUpdate = parseInt(pollData.settings.disallowVoteUpdate, 10); + pollData.settings.privateVotes = parseInt(pollData.settings.privateVotes, 10); + pollData.settings.hiddenVotes = parseInt(pollData.settings.hiddenVotes, 10); callback(null, pollData); }); }; @@ -253,6 +255,18 @@ const Scheduler = require('./scheduler'); Poll.setField(pollId, 'ended', 1); }; + Poll.isPrivateVotes = function (pollId, callback) { + Poll.getSettingsField(pollId, 'privateVotes', (err, result) => { + callback(err, parseInt(result, 10) === 1); + }); + }; + + Poll.isHiddenVotes = function (pollId, callback) { + Poll.getSettingsField(pollId, 'hiddenVotes', (err, result) => { + callback(err, parseInt(result, 10) === 1); + }); + }; + Poll.changePid = function (pollId, pid, callback) { async.parallel([ function (next) { @@ -298,4 +312,4 @@ const Scheduler = require('./scheduler'); Poll.setSettingsField = function (pollId, field, value, callback) { NodeBB.db.setObjectField(`poll:${pollId}:settings`, field, callback); }; -}(exports)); +}(exports)); \ No newline at end of file diff --git a/lib/sockets.js b/lib/sockets.js index 1c6509d..dad7799 100755 --- a/lib/sockets.js +++ b/lib/sockets.js @@ -198,12 +198,31 @@ const Vote = require('./vote'); return callback(null, result); } - NodeBB.User.getUsersFields(result.votes, ['uid', 'username', 'userslug', 'picture'], (err, userData) => { - if (err) { - console.error(err); + async.parallel({ + isAdmin: function(next){ + NodeBB.User.isAdministrator(socket.uid, next); + }, + pollData: function(next){ + Poll.getInfo(data.pollId, next); + }, + privateVotes : function(next){ + Poll.isPrivateVotes(data.pollId, next); + }, + hiddenVotes : function(next){ + Poll.isHiddenVotes(data.pollId, next); + }, + }, (err, data) => { + if (!data.isAdmin && ((data.pollData.uid!==socket.uid && !!data.privateVotes) || !!data.hiddenVotes)) { + result.votes=[]; + return callback(null, result); } - result.votes = userData; - callback(null, result); + NodeBB.User.getUsersFields(result.votes, ['uid', 'username', 'userslug', 'picture'], (err, userData) => { + if (err) { + console.error(err); + } + result.votes = userData; + callback(null, result); + }); }); }); }; @@ -244,4 +263,4 @@ const Vote = require('./vote'); return callback(null, can); }); } -}(exports)); +}(exports)); \ No newline at end of file diff --git a/public/js/poll/creator.js b/public/js/poll/creator.js index 715c3ca..bab0d0a 100755 --- a/public/js/poll/creator.js +++ b/public/js/poll/creator.js @@ -234,6 +234,8 @@ title: obj['settings.title'], maxvotes: obj['settings.maxvotes'], disallowVoteUpdate: obj['settings.disallowVoteUpdate'] === 'on' ? 'true' : 'false', + privateVotes: obj['settings.privateVotes'] === 'on' ? 'true' : 'false', + hiddenVotes: obj['settings.hiddenVotes'] === 'on' ? 'true' : 'false', end: obj['settings.end'], }, }; @@ -251,4 +253,4 @@ Poll.creator = Creator; init(); -}(window.Poll)); +}(window.Poll)); \ No newline at end of file diff --git a/public/js/poll/serializer.js b/public/js/poll/serializer.js index e1867b0..40554f2 100644 --- a/public/js/poll/serializer.js +++ b/public/js/poll/serializer.js @@ -22,6 +22,22 @@ module.exports = function (utils) { return parseInt(value, 10); }, }, + privateVotes: { + test: function (value) { + return /true|false/.test(value); + }, + parse: function (value) { + return value === 'true' || value === true ? 1 : 0; + }, + }, + hiddenVotes: { + test: function (value) { + return /true|false/.test(value); + }, + parse: function (value) { + return value === 'true' || value === true ? 1 : 0; + }, + }, disallowVoteUpdate: { test: function (value) { return /true|false/.test(value); @@ -162,4 +178,4 @@ module.exports = function (utils) { window.Poll.serializer = Serializer; } return Serializer; -}; +}; \ No newline at end of file diff --git a/public/js/poll/view.js b/public/js/poll/view.js index e494799..196f7e5 100644 --- a/public/js/poll/view.js +++ b/public/js/poll/view.js @@ -127,7 +127,7 @@ return Poll.alertError(err.message); } - view.showOptionDetails(details); + view.showOptionDetails({...details, privateVotes: view.isPrivateVotes(), hiddenVotes: view.isHiddenVotes()}); }); }, }, @@ -204,6 +204,14 @@ return parseInt(this.pollData.settings.disallowVoteUpdate, 10) !== 1; }; + View.prototype.isPrivateVotes = function () { + return parseInt(this.pollData.settings.privateVotes, 10) === 1; + }; + + View.prototype.isHiddenVotes = function () { + return parseInt(this.pollData.settings.hiddenVotes, 10) === 1; + }; + View.prototype.pollEndedOrDeleted = function () { if (this.hasPollEndedOrDeleted()) { this.showResultsPanel(); @@ -369,4 +377,4 @@ } }, }; -}(window.Poll)); +}(window.Poll)); \ No newline at end of file diff --git a/templates/poll/creator.tpl b/templates/poll/creator.tpl index e579d53..234b0f7 100755 --- a/templates/poll/creator.tpl +++ b/templates/poll/creator.tpl @@ -33,6 +33,20 @@ +
+
+ + +
+
+ +
+
+ + +
+
+
diff --git a/templates/poll/view/details.tpl b/templates/poll/view/details.tpl index 916df2a..fa28bc2 100644 --- a/templates/poll/view/details.tpl +++ b/templates/poll/view/details.tpl @@ -4,3 +4,10 @@ {buildAvatar(votes, "24px", true)} + +

[[poll:votes_are_hidden]]

+ + +

[[poll:votes_are_private]]

+ +