FEATURE: add alert when less than 10 votes left

This commit is contained in:
Sam 2017-03-08 12:44:30 -05:00
parent 05b66ef3ba
commit b96dd07033
8 changed files with 77 additions and 24 deletions

View File

@ -32,7 +32,9 @@ module DiscourseVoting
can_vote: !current_user.reached_voting_limit?,
vote_limit: current_user.vote_limit,
vote_count: topic.custom_fields["vote_count"].to_i,
who_voted: who_voted(topic)
who_voted: who_voted(topic),
alert: current_user.alert_low_votes?,
votes_left: [(current_user.vote_limit - current_user.vote_count), 0].max
}
render json: obj, status: voted ? 200 : 403
@ -52,7 +54,8 @@ module DiscourseVoting
can_vote: !current_user.reached_voting_limit?,
vote_limit: current_user.vote_limit,
vote_count: topic.custom_fields["vote_count"].to_i,
who_voted: who_voted(topic)
who_voted: who_voted(topic),
votes_left: [(current_user.vote_limit - current_user.vote_count), 0].max
}
render json: obj

View File

@ -1,5 +1,6 @@
import { createWidget } from 'discourse/widgets/widget';
import { ajax } from 'discourse/lib/ajax';
import RawHtml from 'discourse/widgets/raw-html';
export default createWidget('vote-box', {
tagName: 'div.voting-wrapper',
@ -13,11 +14,37 @@ export default createWidget('vote-box', {
return { allowClick: true, initialVote: false };
},
html(attrs){
html(attrs, state){
var voteCount = this.attach('vote-count', attrs);
var voteButton = this.attach('vote-button', attrs);
var voteOptions = this.attach('vote-options', attrs);
return [voteCount, voteButton, voteOptions];
let contents = [voteCount, voteButton, voteOptions];
if (state.votesAlert > 0) {
const html = "<div class='voting-popup-menu vote-options popup-menu'>" + I18n.t("voting.votes_left", {
count: state.votesAlert,
path: this.currentUser.get("path") + "/activity/votes"
}) + "</div>";
contents.push(new RawHtml({html}));
}
return contents;
},
hideVotesAlert() {
if (this.state.votesAlert) {
this.state.votesAlert = null;
this.scheduleRerender();
}
},
click() {
this.hideVotesAlert();
},
clickOutside(){
this.hideVotesAlert();
},
addVote(){
@ -28,10 +55,15 @@ export default createWidget('vote-box', {
data: {
topic_id: topic.id
}
}).then(function(result) {
}).then((result) => {
topic.set('vote_count', result.vote_count);
topic.set('user_voted', true);
Discourse.User.current().set('votes_exceeded', !result.can_vote);
let currentUser = Discourse.User.current();
currentUser.set('votes_exceeded', !result.can_vote);
if (result.alert) {
state.votesAlert = result.votes_left;
this.scheduleRerender();
}
topic.set('who_voted', result.who_voted);
state.allowClick = true;
}).catch(function(error) {

View File

@ -7,7 +7,7 @@ export default createWidget('vote-button', {
buildClasses(attrs) {
var buttonClass = "";
if (attrs.closed){
buttonClass = "voting-closed nonvote";
buttonClass = "voting-closed";
}
else{
if (!attrs.user_voted){
@ -58,12 +58,12 @@ export default createWidget('vote-button', {
if (!this.currentUser){
showModal('login');
}
if (!this.attrs.closed && this.parentWidget.state.allowClick && !this.attrs.user_voted && !this.currentUser.votes_exceeded){
if (!this.attrs.closed && this.parentWidget.state.allowClick && !this.attrs.user_voted){
this.parentWidget.state.allowClick = false;
this.parentWidget.state.initialVote = true;
this.sendWidgetAction('addVote');
}
if (this.attrs.user_voted) {
if (this.attrs.user_voted || this.currentUser.votes_exceeded) {
$(".vote-options").toggle();
}
},

View File

@ -1,4 +1,5 @@
import { createWidget } from 'discourse/widgets/widget';
import { h } from 'virtual-dom';
export default createWidget('vote-options', {
tagName: 'div.vote-options',
@ -9,9 +10,18 @@ export default createWidget('vote-options', {
html(attrs){
var contents = [];
if (attrs.user_voted){
contents.push(this.attach('remove-vote', attrs));
}
else if (this.currentUser && this.currentUser.votes_exceeded && !attrs.user_voted) {
contents.push([
h("div", I18n.t("voting.reached_limit")),
h("p",
h("a",{ href: this.currentUser.get("path") + "/activity/votes" }, I18n.t("voting.list_votes"))
)
]);
}
return contents;
}
});

View File

@ -31,18 +31,15 @@
padding-top:14px;
position: relative;
}
.vote-button{
background-color: #e9e9e9;
.vote-button {
display: block;
margin-top: 5px;
padding: 2px 0px;
color: #222222 !important;
cursor: pointer;
}
.vote-button.nonvote {
color: #ffffff !important;
background-color: $tertiary;
margin-top: 5px;
padding: 2px 0px;
color: #ffffff;
background-color: $tertiary;
cursor: pointer;
}
.vote-options{
text-align: left;
}
@ -99,7 +96,7 @@
display: inline-block;
}
}
.voting-popup-menu{
.voting-popup-menu {
position: absolute !important;
left: 80px !important;
top: 14px !important;

View File

@ -1,6 +1,8 @@
en:
js:
voting:
reached_limit: "You are out of votes, remove an existing vote!"
list_votes: "List your votes"
votes_nav_help: "topics with the most votes"
voted: "You voted on this topic"
allow_topic_voting: "Allow users to vote on topics in this category"
@ -9,6 +11,9 @@ en:
voted_title: "Voted"
voting_closed_title: "Closed"
voting_limit: "Limit"
votes_left:
one: "You have 1 vote left, see <a href='{{path}}'>your votes</a>."
other: "You have {{count}} votes left, see <a href='{{path}}'>your votes</a>."
votes:
one: "1 vote"
other: "{{count}} votes"

View File

@ -1,4 +1,6 @@
plugins:
voting_alert_votes_left:
default: 10
voting_enabled:
default: true
client: true
@ -9,12 +11,12 @@ plugins:
default: true
client: true
voting_tl0_vote_limit:
default: 3
default: 2
voting_tl1_vote_limit:
default: 5
default: 4
voting_tl2_vote_limit:
default: 8
default: 6
voting_tl3_vote_limit:
default: 10
default: 8
voting_tl4_vote_limit:
default: 10

View File

@ -114,6 +114,10 @@ after_initialize do
end
end
def alert_low_votes?
(vote_limit - vote_count) <= SiteSetting.voting_alert_votes_left
end
def votes
if self.custom_fields["votes"]
self.custom_fields["votes"]