Merge pull request #5118 from consuldemocracy/undo-votes
Allow undoing "like/unlike" votes
This commit is contained in:
@@ -3,22 +3,16 @@
|
||||
|
|
||||
|
||||
<span class="in-favor">
|
||||
<%= button_to vote_comment_path(comment, value: "yes"),
|
||||
method: "post",
|
||||
remote: can?(:vote, comment),
|
||||
title: t("votes.agree") do %>
|
||||
<span class="show-for-sr"><%= t("votes.agree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(comment,
|
||||
value: "yes",
|
||||
title: t("votes.agree")) %>
|
||||
<%= comment.total_likes %>
|
||||
</span>
|
||||
|
||||
<span class="against">
|
||||
<%= button_to vote_comment_path(comment, value: "no"),
|
||||
method: "post",
|
||||
remote: can?(:vote, comment),
|
||||
title: t("votes.disagree") do %>
|
||||
<span class="show-for-sr"><%= t("votes.disagree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(comment,
|
||||
value: "no",
|
||||
title: t("votes.disagree")) %>
|
||||
<%= comment.total_dislikes %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class Comments::VotesComponent < ApplicationComponent
|
||||
attr_reader :comment
|
||||
delegate :can?, to: :helpers
|
||||
|
||||
def initialize(comment)
|
||||
@comment = comment
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Legislation::Proposals::VotesComponent < ApplicationComponent
|
||||
attr_reader :proposal
|
||||
delegate :current_user, :link_to_verify_account, to: :helpers
|
||||
delegate :current_user, :link_to_verify_account, :can?, to: :helpers
|
||||
|
||||
def initialize(proposal)
|
||||
@proposal = proposal
|
||||
@@ -9,7 +9,7 @@ class Legislation::Proposals::VotesComponent < ApplicationComponent
|
||||
private
|
||||
|
||||
def can_vote?
|
||||
proposal.votable_by?(current_user)
|
||||
can?(:create, proposal.votes_for.new(voter: current_user))
|
||||
end
|
||||
|
||||
def cannot_vote_text
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
<div class="in-favor-against">
|
||||
<div class="in-favor">
|
||||
<%= button_to polymorphic_path(votable, action: :vote, value: "yes"),
|
||||
class: "like #{voted_classes[:in_favor]}",
|
||||
title: t("votes.agree"),
|
||||
"aria-label": agree_aria_label,
|
||||
method: "post",
|
||||
remote: true do %>
|
||||
<span class="show-for-sr"><%= t("votes.agree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(votable,
|
||||
value: "yes",
|
||||
"aria-label": agree_aria_label,
|
||||
title: t("votes.agree")) %>
|
||||
<span class="percentage"><%= votes_percentage("likes", votable) %></span>
|
||||
</div>
|
||||
|
||||
<div class="against">
|
||||
<%= button_to polymorphic_path(votable, action: :vote, value: "no"),
|
||||
class: "unlike #{voted_classes[:against]}",
|
||||
title: t("votes.disagree"),
|
||||
"aria-label": disagree_aria_label,
|
||||
method: "post",
|
||||
remote: true do %>
|
||||
<span class="show-for-sr"><%= t("votes.disagree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(votable,
|
||||
value: "no",
|
||||
"aria-label": disagree_aria_label,
|
||||
title: t("votes.disagree")) %>
|
||||
<span class="percentage"><%= votes_percentage("dislikes", votable) %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Shared::InFavorAgainstComponent < ApplicationComponent
|
||||
attr_reader :votable
|
||||
delegate :current_user, :votes_percentage, to: :helpers
|
||||
delegate :votes_percentage, to: :helpers
|
||||
|
||||
def initialize(votable)
|
||||
@votable = votable
|
||||
@@ -8,21 +8,6 @@ class Shared::InFavorAgainstComponent < ApplicationComponent
|
||||
|
||||
private
|
||||
|
||||
def voted_classes
|
||||
@voted_classes ||= css_classes_for_vote
|
||||
end
|
||||
|
||||
def css_classes_for_vote
|
||||
case current_user&.voted_as_when_voted_for(votable)
|
||||
when true
|
||||
{ in_favor: "voted", against: "no-voted" }
|
||||
when false
|
||||
{ in_favor: "no-voted", against: "voted" }
|
||||
else
|
||||
{ in_favor: "", against: "" }
|
||||
end
|
||||
end
|
||||
|
||||
def agree_aria_label
|
||||
t("votes.agree_label", title: votable.title)
|
||||
end
|
||||
|
||||
3
app/components/shared/vote_button_component.html.erb
Normal file
3
app/components/shared/vote_button_component.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<%= button_to path, default_options.merge(options) do %>
|
||||
<span class="show-for-sr"><%= options[:title] %></span>
|
||||
<% end %>
|
||||
48
app/components/shared/vote_button_component.rb
Normal file
48
app/components/shared/vote_button_component.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class Shared::VoteButtonComponent < ApplicationComponent
|
||||
attr_reader :votable, :value, :options
|
||||
delegate :current_user, :can?, to: :helpers
|
||||
|
||||
def initialize(votable, value:, **options)
|
||||
@votable = votable
|
||||
@value = value
|
||||
@options = options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def path
|
||||
if already_voted?
|
||||
polymorphic_path(vote)
|
||||
else
|
||||
polymorphic_path(vote, value: value)
|
||||
end
|
||||
end
|
||||
|
||||
def default_options
|
||||
if already_voted?
|
||||
{
|
||||
"aria-pressed": true,
|
||||
method: :delete,
|
||||
remote: can?(:destroy, vote)
|
||||
}
|
||||
else
|
||||
{
|
||||
"aria-pressed": false,
|
||||
method: :post,
|
||||
remote: can?(:create, vote)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def vote
|
||||
@vote ||= Vote.find_or_initialize_by(votable: votable, voter: current_user, vote_flag: parsed_value)
|
||||
end
|
||||
|
||||
def already_voted?
|
||||
vote.persisted?
|
||||
end
|
||||
|
||||
def parsed_value
|
||||
value == "yes"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user