Skip to content

Commit

Permalink
Merge pull request #8 from angusmcleod/vote_count_to_custom_fields
Browse files Browse the repository at this point in the history
Store vote count, vote user and vote history in post custom fields && Integrate custom storage into a functionality consistent vote post action
  • Loading branch information
angusmcleod committed Jul 13, 2018
2 parents 89fee2f + 6803504 commit 257a6c6
Show file tree
Hide file tree
Showing 13 changed files with 487 additions and 118 deletions.
@@ -0,0 +1,7 @@
export default {
setupComponent(attrs) {
if (!attrs.category.custom_fields) {
attrs.category.custom_fields = {};
}
}
};
41 changes: 37 additions & 4 deletions assets/javascripts/discourse/initializers/qa-edits.js.es6
Expand Up @@ -4,6 +4,8 @@ import { h } from 'virtual-dom';
import { avatarImg, avatarFor } from 'discourse/widgets/post';
import { dateNode, numberNode } from 'discourse/helpers/node';
import { REPLY } from "discourse/models/composer";
import { undoVote, whoVoted, voteActionId } from '../lib/qa-utilities';
import { avatarAtts } from 'discourse/widgets/actions-summary';

export default {
name: 'qa-edits',
Expand Down Expand Up @@ -144,14 +146,45 @@ export default {
});

api.attachWidgetAction('post', 'undoPostAction', function(typeId) {
const post = this.model;
if (typeId === 5) {

if (typeId === voteActionId) {
const post = this.model;
const user = this.currentUser;

post.set('topic.voted', false);

let vote = {
user_id: user.id,
post_id: post.id,
direction: 'up'
}

undoVote({ vote });
} else {
this._super(typeId);
}
});

api.reopenWidget('actions-summary-item', {
whoActed() {
const attrs = this.attrs;

if (attrs.id === voteActionId) {
whoVoted({
post_id: attrs.postId
}).then(result => {
if (result.voters) {
this.state.users = result.voters.map(avatarAtts);
this.scheduleRerender();
}
});
} else {
this._super();
}
}
return post.get('actions_summary').findBy('id', typeId).undo(post);
});

api.modifyClass('model:topic', {
api.modifyClass('model:topic', {
@computed('qa_enabled')
showQaTip(qaEnabled) {
return qaEnabled && this.siteSettings.qa_show_topic_tip;
Expand Down
28 changes: 28 additions & 0 deletions assets/javascripts/discourse/lib/qa-utilities.js.es6
@@ -0,0 +1,28 @@
import { popupAjaxError } from 'discourse/lib/ajax-error';
import { ajax } from 'discourse/lib/ajax';

const voteActionId = 100;

const vote = function(type, data) {
return ajax('/qa/vote', {
type,
data
}).catch(popupAjaxError)
}

const undoVote = function(data) {
return vote('DELETE', data);
}

const castVote = function(data) {
return vote('POST', data);
}

const whoVoted = function(data) {
return ajax('/qa/voters', {
type: 'GET',
data
}).catch(popupAjaxError)
}

export { undoVote, castVote, voteActionId, whoVoted };
2 changes: 1 addition & 1 deletion assets/javascripts/discourse/widgets/qa-button.js.es6
Expand Up @@ -8,6 +8,6 @@ export default createWidget('qa-button', {
},

click() {
this.sendWidgetAction('vote');
this.sendWidgetAction('vote', this.attrs.direction);
}
});
19 changes: 15 additions & 4 deletions assets/javascripts/discourse/widgets/qa-post.js.es6
@@ -1,4 +1,5 @@
import { createWidget } from 'discourse/widgets/widget';
import { castVote } from '../lib/qa-utilities';
import { h } from 'virtual-dom';

export default createWidget('qa-post', {
Expand All @@ -17,17 +18,27 @@ export default createWidget('qa-post', {
return contents;
},

vote() {
vote(direction) {
const post = this.attrs.post;
const user = this.currentUser;

if (post.get('topic.voted')) {
return bootbox.alert(I18n.t('vote.already_voted'));
}
if (!this.currentUser) {

if (!user) {
return this.sendShowLogin();
}

post.set('topic.voted', true);
const voteAction = post.get('actions_summary').findBy('id', 5);
voteAction.act(post);

let vote = {
user_id: user.id,
post_id: post.id,
direction
};

castVote({ vote });
}

});
24 changes: 22 additions & 2 deletions config/locales/client.en.yml
@@ -1,5 +1,8 @@
en:
js:
category:
enable_qa: "Make all topics in this category QnA."

composer:
composer_actions:
reply_to_question:
Expand All @@ -8,6 +11,24 @@ en:
comment_on_answer:
label: Comment on answer of %{postUsername}
desc: Comment on an answer

post:
actions:
undo:
vote: "Undo vote"
people:
vote: "voted for this"
by_you:
vote: "You voted for this post"
by_you_and_others:
vote:
one: "You and 1 other voted for this post"
other: "You and {{count}} other people voted for this post"
by_others:
vote:
one: "1 person voted for this post"
other: "{{count}} people voted for this post"

topic:
answer:
title: 'Answer'
Expand All @@ -22,8 +43,7 @@ en:
details: "Users can vote for the response that best answers the initial post.
<ul><li>Each user is allowed one vote.</li>
<li>Responses are ordered by vote count.</li></ul>"
category:
enable_qa: "Make all topics in this category QnA."

vote:
already_voted: "You can only vote once per question."

Expand Down
13 changes: 12 additions & 1 deletion config/locales/server.en.yml
Expand Up @@ -5,5 +5,16 @@ en:
qa_enabled: "Enable QA Plugin"
qa_disable_like_on_answers: "Disables like button on answers in QnA topics"
qa_undo_vote_action_window: "Number of minutes users are allowed to undo votes in QnA topics (enter 0 for no limit)"

post_action_types:
vote:
title: 'Vote'
description: 'Vote for this post'
short_description: 'Vote for this post'
long_form: 'voted for this post'

vote:
already_voted: "You can only vote once per question."
error:
user_has_not_voted: "User has not voted."
already_voted: "You can only vote once per question."
undo_vote_action_window: "You can only undo votes %{minutes} after voting."
@@ -0,0 +1,47 @@
class SaveExistingPostVoteCountsToCustomFields < ActiveRecord::Migration[5.2]
def up
vote_totals = {}

PostAction.where(post_action_type_id: 5).each do |action|
if post = Post.find_by(id: action[:post_id])
votes = post.vote_history

votes.push(
"direction": QuestionAnswer::Vote::UP,
"action": QuestionAnswer::Vote::CREATE,
"user_id": action[:user_id].to_s,
"created_at": action[:created_at]
)

post.custom_fields['vote_history'] = votes.to_json
post.save_custom_fields(true)
end

total = vote_totals[action[:post_id]]
total = { count: 0, voted: [] } if total == nil

total[:count] += 1

voted = total[:voted]
voted.push(action[:user_id])
total[:voted] = voted

vote_totals[action[:post_id]] = total
end

if vote_totals.any?
vote_totals.each do |k, v|
if post = Post.find_by(id: k)
post.custom_fields['vote_history'] = post.vote_history.to_json
post.custom_fields['vote_count'] = v[:count].to_i
post.custom_fields['voted'] = v[:voted]
post.save_custom_fields(true)
end
end
end
end

def down
raise ActiveRecord::IrreversibleMigration
end
end

0 comments on commit 257a6c6

Please sign in to comment.