diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index aa6da3a80..3ba96f0c8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -78,6 +78,10 @@ class ApplicationController < ActionController::Base @debate_votes = current_user ? current_user.debate_votes(debates) : {} end + def set_proposal_votes(proposals) + @proposal_votes = current_user ? current_user.proposal_votes(proposals) : {} + end + def set_comment_flags(comments) @comment_flags = current_user ? current_user.comment_flags(comments) : {} end diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index efad5783e..c788d3ba9 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -5,7 +5,13 @@ class ProposalsController < ApplicationController respond_to :html, :js def show - render text: "" + set_proposal_votes(@proposal) + @commentable = @proposal + @root_comments = @proposal.comments.roots.recent.page(params[:page]).per(10).for_render + @comments = @root_comments.inject([]){|all, root| all + Comment.descendants_of(root).for_render} + + @all_visible_comments = @root_comments + @comments + set_comment_flags(@all_visible_comments) end def new diff --git a/app/helpers/votes_helper.rb b/app/helpers/votes_helper.rb index dfc1bbda0..fa25fcca7 100644 --- a/app/helpers/votes_helper.rb +++ b/app/helpers/votes_helper.rb @@ -11,4 +11,13 @@ module VotesHelper end end + def css_classes_for_proposal_vote(proposal_votes, proposal) + case proposal_votes[proposal.id] + when true + {in_favor: "voted"} + else + {in_favor: ""} + end + end + end diff --git a/app/models/proposal.rb b/app/models/proposal.rb index e956e64e8..3892686af 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -1,12 +1,12 @@ class Proposal < ActiveRecord::Base apply_simple_captcha + acts_as_votable + acts_as_taggable belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' has_many :comments, as: :commentable has_many :flags, as: :flaggable - acts_as_taggable - validates :title, presence: true validates :question, presence: true validates :description, presence: true @@ -21,6 +21,28 @@ class Proposal < ActiveRecord::Base before_validation :sanitize_description before_validation :sanitize_tag_list + def total_votes + cached_votes_up + end + + def conflictive? + return false unless flags_count > 0 && cached_votes_up > 0 + cached_votes_up/flags_count.to_f < 5 + end + + def tag_list_with_limit(limit = nil) + return tags if limit.blank? + + tags.sort{|a,b| b.taggings_count <=> a.taggings_count}[0, limit] + end + + def tags_count_out_of_limit(limit = nil) + return 0 unless limit + + count = tags.size - limit + count < 0 ? 0 : count + end + def self.title_max_length @@title_max_length ||= self.columns.find { |c| c.name == 'title' }.limit || 80 end @@ -33,6 +55,18 @@ class Proposal < ActiveRecord::Base 6000 end + def editable? + total_votes <= 1000 + end + + def editable_by?(user) + editable? && author == user + end + + def votable_by?(user) + user.level_two_verified? || !user.voted_for?(self) + end + protected def sanitize_description diff --git a/app/models/user.rb b/app/models/user.rb index 3ddf4df54..4bbd989f4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -86,6 +86,11 @@ class User < ActiveRecord::Base voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value } end + def proposal_votes(proposals) + voted = votes.for_proposals(proposals) + voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value } + end + def comment_flags(comments) comment_flags = flags.for_comments(comments) comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true } diff --git a/app/views/proposals/_actions.html.erb b/app/views/proposals/_actions.html.erb new file mode 100644 index 000000000..b2bc9f111 --- /dev/null +++ b/app/views/proposals/_actions.html.erb @@ -0,0 +1,10 @@ +<% if can? :hide, proposal %> + <%= link_to t("admin.actions.hide").capitalize, hide_moderation_proposal_path(proposal), + method: :put, remote: true, data: { confirm: t('admin.actions.confirm') } %> +<% end %> + +<% if can? :hide, proposal.author %> +  |  + <%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(proposal.author_id), + method: :put, data: { confirm: t('admin.actions.confirm') } %> +<% end %> diff --git a/app/views/proposals/_comments.html.erb b/app/views/proposals/_comments.html.erb new file mode 100644 index 000000000..6270c58b6 --- /dev/null +++ b/app/views/proposals/_comments.html.erb @@ -0,0 +1,27 @@ +
+
+
+

+ <%= t("proposals.show.comments_title") %> + (<%= @proposal.comments_count %>) +

+ + <% if user_signed_in? %> + <%= render 'comments/form', {commentable: @proposal, parent_id: nil, toggeable: false} %> + <% else %> +
+ +
+ <%= t("proposals.show.login_to_comment", + signin: link_to(t("votes.signin"), new_user_session_path), + signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %> +
+ <% end %> + + <% @root_comments.each do |comment| %> + <%= render 'comments/comment', comment: comment %> + <% end %> + <%= paginate @root_comments %> +
+
+
\ No newline at end of file diff --git a/app/views/proposals/_flag_actions.html.erb b/app/views/proposals/_flag_actions.html.erb new file mode 100644 index 000000000..b7bea4f79 --- /dev/null +++ b/app/views/proposals/_flag_actions.html.erb @@ -0,0 +1,21 @@ +<% if show_flag_action? proposal %> + + +<% end %> + +<% if show_unflag_action? proposal %> + + +<% end %> diff --git a/app/views/proposals/_votes.html.erb b/app/views/proposals/_votes.html.erb new file mode 100644 index 000000000..9c6188b87 --- /dev/null +++ b/app/views/proposals/_votes.html.erb @@ -0,0 +1,37 @@ +<% voted_classes = css_classes_for_proposal_vote(@proposal_votes, proposal) %> +
+
+ <%= link_to vote_proposal_path(proposal, value: 'yes'), + class: "like #{voted_classes[:in_favor]}", title: t('votes.agree'), method: "post", remote: true do %> + + <%= percentage('likes', proposal) %> + <% end %> +
+ + + + + <%= t("proposals.proposal.votes", count: proposal.total_votes) %> + + + <% if user_signed_in? && current_user.organization? %> + + <% elsif user_signed_in? && !proposal.votable_by?(current_user)%> + + <% elsif !user_signed_in? %> + + <% end %> +
diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb new file mode 100644 index 000000000..b25bf3277 --- /dev/null +++ b/app/views/proposals/show.html.erb @@ -0,0 +1,83 @@ +
+
+
+   + <%= link_to t("proposals.show.back_link"), proposals_path, class: 'left back' %> + + <% if current_user && @proposal.editable_by?(current_user) %> + <%= link_to edit_proposal_path(@proposal), class: 'edit-proposal button success tiny radius right' do %> + + <%= t("proposals.show.edit_proposal_link") %> + <% end %> + <% end %> + +

<%= @proposal.title %>

+ <% if @proposal.conflictive? %> +
+ <%= t("proposals.show.flag") %> +
+ <% end %> + +
+ <%= avatar_image(@proposal.author, seed: @proposal.author_id, size: 32, class: 'author-photo') %> + + <% if @proposal.author.hidden? %> + + + <%= t("proposals.show.author_deleted") %> + + <% else %> + + <%= @proposal.author.name %> + + <% if @proposal.author.official? %> +  •  + + <%= @proposal.author.official_position %> + + <% end %> + <% end %> + + <% if @proposal.author.verified_organization? %> +  •  + + <%= t("shared.collective") %> + + <% end %> + +  •  + <%= l @proposal.created_at.to_date %> +  •  +   + <%= link_to t("proposals.show.comments", count: @proposal.comments_count), "#comments" %> +  •  + + <%= render 'proposals/flag_actions', proposal: @proposal %> + +
+ + <%= @proposal.description %> + + <%= render 'shared/tags', proposal: @proposal %> + +
+ <%= render 'actions', proposal: @proposal %> +
+
+ + +
+
+ +<%= render "comments" %> diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb index ea3f65c6b..206b29759 100644 --- a/app/views/shared/_tags.html.erb +++ b/app/views/shared/_tags.html.erb @@ -1,13 +1,15 @@ <%- limit ||= nil %> +<%= taggable = defined?(debate) ? debate : proposal %> -<% if debate.tags.any? %> +<% if taggable.tags.any? %> - <% debate.tag_list_with_limit(limit).each do |tag| %> - <%= link_to sanitize(tag.name), debates_path(tag: tag.name) %> + <% taggable.tag_list_with_limit(limit).each do |tag| %> + <%= link_to sanitize(tag.name), send("#{taggable.class.to_s.downcase}_path", tag: tag.name) %> <% end %> - <% if debate.tags_count_out_of_limit(limit) > 0 %> - <%= link_to "#{debate.tags_count_out_of_limit(limit)}+", debate_path(debate) %> + <% if taggable.tags_count_out_of_limit(limit) > 0 %> + <%= link_to "#{taggable.tags_count_out_of_limit(limit)}+", + send("#{taggable.class.to_s.downcase}_path", taggable) %> <% end %> <% end %> \ No newline at end of file diff --git a/config/initializers/vote_extensions.rb b/config/initializers/vote_extensions.rb index c0a92ef40..2a77bbef6 100644 --- a/config/initializers/vote_extensions.rb +++ b/config/initializers/vote_extensions.rb @@ -3,6 +3,10 @@ ActsAsVotable::Vote.class_eval do where(votable_type: 'Debate', votable_id: debates) end + def self.for_proposals(proposals) + where(votable_type: 'Debate', votable_id: proposals) + end + def value vote_flag end diff --git a/config/routes.rb b/config/routes.rb index 7246c0807..65e5850aa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,7 +45,21 @@ Rails.application.routes.draw do end end - resources :proposals + resources :proposals do + member do + post :vote + put :flag + put :unflag + end + + resources :comments, only: :create, shallow: true do + member do + post :vote + put :flag + put :unflag + end + end + end resource :account, controller: "account", only: [:show, :update] resource :verification, controller: "verification", only: [:show]