From d0a77ce6b3a9a0cefa1fc04c9caa665595ba569f Mon Sep 17 00:00:00 2001 From: Jannik Streek Date: Mon, 24 Mar 2014 19:43:52 +0100 Subject: [PATCH] design for poll participation implemented, saving works as well --- .../app/models/poll_participation.js | 5 ++ .../javascripts/app/models/status_message.js | 3 +- app/assets/javascripts/app/views/poll.js | 50 +++++++++++++++++++ .../javascripts/app/views/publisher_view.js | 2 +- .../app/views/stream_post_views.js | 2 + app/assets/stylesheets/application.css.sass | 1 + app/assets/stylesheets/poll.css.scss | 43 ++++++++++++++++ app/assets/templates/poll_tpl.jst.hbs | 19 +++++++ .../templates/status-message_tpl.jst.hbs | 1 + .../poll_participations_controller.rb | 30 +++++++++++ app/controllers/status_messages_controller.rb | 20 ++++---- app/models/poll.rb | 18 +++++++ app/models/poll_answer.rb | 2 + app/models/post.rb | 3 ++ app/presenters/post_presenter.rb | 1 + config/locales/javascript/javascript.en.yml | 4 ++ config/routes.rb | 4 ++ lib/federated/generator.rb | 2 - 18 files changed, 197 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/app/models/poll_participation.js create mode 100644 app/assets/javascripts/app/views/poll.js create mode 100644 app/assets/stylesheets/poll.css.scss create mode 100644 app/assets/templates/poll_tpl.jst.hbs create mode 100644 app/controllers/poll_participations_controller.rb diff --git a/app/assets/javascripts/app/models/poll_participation.js b/app/assets/javascripts/app/models/poll_participation.js new file mode 100644 index 000000000..a31c35779 --- /dev/null +++ b/app/assets/javascripts/app/models/poll_participation.js @@ -0,0 +1,5 @@ +app.models.PollParticipation = Backbone.Model.extend({ + url : function(){ + "/poll_participations" + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/app/models/status_message.js b/app/assets/javascripts/app/models/status_message.js index 07f8f2f53..bce96553d 100644 --- a/app/assets/javascripts/app/models/status_message.js +++ b/app/assets/javascripts/app/models/status_message.js @@ -13,7 +13,8 @@ app.models.StatusMessage = app.models.Post.extend({ status_message : _.clone(this.attributes), aspect_ids : this.get("aspect_ids"), photos : this.photos && this.photos.pluck("id"), - services : this.get("services") + services : this.get("services"), + poll : this.get("poll") } } }); diff --git a/app/assets/javascripts/app/views/poll.js b/app/assets/javascripts/app/views/poll.js new file mode 100644 index 000000000..c7f9ebaab --- /dev/null +++ b/app/assets/javascripts/app/views/poll.js @@ -0,0 +1,50 @@ +app.views.Poll = app.views.Base.extend({ + templateName : "poll", + + events : { + "click .submit" : "vote" + }, + + initialize : function(options) { + this.poll = this.model.attributes.poll; + this.progressBarFactor = 3; + //this.model.bind('remove', this.remove, this); + }, + + postRenderTemplate : function() { + if(this.poll) { + this.setProgressBar(); + } + }, + + setProgressBar : function() { + var answers = this.poll.poll_answers; + for(index = 0; index < answers.length; ++index) { + var percentage = 0; + if(this.poll.participation_count != 0) { + percentage = answers[index].vote_count / this.poll.participation_count * 100; + } + var input = this.$("input[value="+answers[index].id+"]"); + var progressBar = $(input).parent().find(".poll_progress_bar"); + var width = percentage * this.progressBarFactor; + progressBar.css("width", width + "px"); + } + // + }, + + vote : function(evt){ + var result = parseInt($(evt.target).parent().find("input[name=vote]:checked").val()); + var pollParticipation = new app.models.PollParticipation(); + pollParticipation.save({ + "poll_answer_id" : result, + "poll_id" : this.poll.poll_id, + },{ + url : "/posts/"+this.poll.post_id+"/poll_participations", + success : function() { + console.log(success); + //todo remove radios+input + } + }); + } + +}); \ No newline at end of file diff --git a/app/assets/javascripts/app/views/publisher_view.js b/app/assets/javascripts/app/views/publisher_view.js index 4f020d7f7..dc51575a9 100644 --- a/app/assets/javascripts/app/views/publisher_view.js +++ b/app/assets/javascripts/app/views/publisher_view.js @@ -192,7 +192,7 @@ app.views.Publisher = Backbone.View.extend({ var clone = this.el_poll_answer.clone(); var answer = clone.find('.poll_answer_input'); - //answer.attr("name", "poll_answer_" + this.option_counter); + answer.val(""); var placeholder = answer.attr("placeholder"); var expression = /[^0-9]+/; diff --git a/app/assets/javascripts/app/views/stream_post_views.js b/app/assets/javascripts/app/views/stream_post_views.js index d8a9551e0..fb1d846d4 100644 --- a/app/assets/javascripts/app/views/stream_post_views.js +++ b/app/assets/javascripts/app/views/stream_post_views.js @@ -9,6 +9,7 @@ app.views.StreamPost = app.views.Post.extend({ ".post-content" : "postContentView", ".oembed" : "oEmbedView", ".opengraph" : "openGraphView", + ".poll" : "pollView", ".status-message-location" : "postLocationStreamView" }, @@ -31,6 +32,7 @@ app.views.StreamPost = app.views.Post.extend({ this.commentStreamView = new app.views.CommentStream({model : this.model}); this.oEmbedView = new app.views.OEmbed({model : this.model}); this.openGraphView = new app.views.OpenGraph({model : this.model}); + this.pollView = new app.views.Poll({model : this.model}); }, diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass index c0555449e..08b7a445b 100644 --- a/app/assets/stylesheets/application.css.sass +++ b/app/assets/stylesheets/application.css.sass @@ -10,6 +10,7 @@ @import 'header' @import 'footer' @import 'opengraph' +@import 'poll' @import 'help' @import 'profile' @import 'publisher_blueprint' diff --git a/app/assets/stylesheets/poll.css.scss b/app/assets/stylesheets/poll.css.scss new file mode 100644 index 000000000..913bd69be --- /dev/null +++ b/app/assets/stylesheets/poll.css.scss @@ -0,0 +1,43 @@ +.poll_form { + display: block; + margin: 10px 0px 10px 0px; + border-top: solid 1px $border-grey; + border-bottom: solid 1px $border-grey; + padding: 10px 0px 5px 0px; + overflow: hidden; + width: 100%; +} + +.poll_form input[type="radio"] { + display:inline !important; +} + +.poll_result { + width:100%px; + display:inline; +} + +.poll_progress_bar { + position:absolute; + width:100px; + height:15px; + top:-10px; + z-index:-1; + background-color:#3f8fba; +} + +.poll_statistic{ + float:right; +} + +.poll_progress_bar_wrapper { + position: relative; + width: 0; + height: 0; + display:inline-block; +} + +.poll_answer_entry{ + display:inline; + width:100%; +} diff --git a/app/assets/templates/poll_tpl.jst.hbs b/app/assets/templates/poll_tpl.jst.hbs new file mode 100644 index 000000000..6cac9b4d2 --- /dev/null +++ b/app/assets/templates/poll_tpl.jst.hbs @@ -0,0 +1,19 @@ +{{#if poll}} +
+

{{t "poll.result" votes=poll.participation_count}}

+ {{poll.question}}
+ {{#poll.poll_answers}} +
+ +
+
+
+
+ {{answer}} +
+
+
+ {{/poll.poll_answers}} + +
+{{/if}} \ No newline at end of file diff --git a/app/assets/templates/status-message_tpl.jst.hbs b/app/assets/templates/status-message_tpl.jst.hbs index 166c8cb1d..761dc57c6 100644 --- a/app/assets/templates/status-message_tpl.jst.hbs +++ b/app/assets/templates/status-message_tpl.jst.hbs @@ -18,4 +18,5 @@ {{{text}}}
+
diff --git a/app/controllers/poll_participations_controller.rb b/app/controllers/poll_participations_controller.rb new file mode 100644 index 000000000..b2d435bb8 --- /dev/null +++ b/app/controllers/poll_participations_controller.rb @@ -0,0 +1,30 @@ +class PollParticipationsController < ApplicationController + include ApplicationHelper + before_filter :authenticate_user! + + def create + answer = PollAnswer.find(params[:poll_answer_id]) + poll_participation = current_user.participate_in_poll!(target, answer) if target rescue ActiveRecord::RecordInvalid + if poll_participation + respond_to do |format| + format.html { redirect_to :back } + format.mobile { redirect_to stream_path } + format.json { render :nothing => true, :status => 201 } + end + else + respond_to do |format| + format.html { redirect_to :back } + format.mobile { redirect_to stream_path } + format.json { render :nothing => true, :status => 403 } + end + end + end + + private + + def target + @target ||= if params[:post_id] + current_user.find_visible_shareable_by_id(Post, params[:post_id]) || raise(ActiveRecord::RecordNotFound.new) + end + end +end \ No newline at end of file diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index 1a083d31c..c2b2e2508 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -49,16 +49,18 @@ class StatusMessagesController < ApplicationController @status_message = current_user.build_post(:status_message, params[:status_message]) @status_message.build_location(:address => params[:location_address], :coordinates => params[:location_coords]) if params[:location_address].present? - @status_message.build_poll(:question => params[:poll_question]) if params[:poll_question].present? - poll_answers = params[:poll_answers] - if params[:poll_answers].instance_of? String - poll_answers = [params[:poll_answers]] - end - - poll_answers.each do |poll_answer| - @status_message.poll.poll_answers.build(:answer => poll_answer) + if params[:poll_question].present? + @status_message.build_poll(:question => params[:poll_question]) + poll_answers = params[:poll_answers] + if params[:poll_answers].instance_of? String + poll_answers = [params[:poll_answers]] + end + poll_answers.each do |poll_answer| + @status_message.poll.poll_answers.build(:answer => poll_answer) + end end + @status_message.attach_photos_by_ids(params[:photos]) if @status_message.save @@ -88,7 +90,7 @@ class StatusMessagesController < ApplicationController respond_to do |format| format.html { redirect_to :back } format.mobile { redirect_to stream_path } - format.json { render {:nothing => true} , :status => 403 } + format.json { render :nothing => true, :status => 403 } end end end diff --git a/app/models/poll.rb b/app/models/poll.rb index df01f127a..1450701b4 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -14,8 +14,26 @@ class Poll < ActiveRecord::Base validate :enough_poll_answers + #TODO check if user has the right to vote + + self.include_root_in_json = false + def enough_poll_answers errors.add(:poll_answers, I18n.t("activerecord.errors.models.poll.attributes.poll_answers.not_enough_poll_answers")) if poll_answers.size < 2 end + def as_json(options={}) + { + :poll_id => self.id, + :post_id => self.status_message.id, + :question => self.question, + :poll_answers => self.poll_answers, + :participation_count => self.participation_count + #TODO already participated? + } + end + + def participation_count + poll_answers.sum("vote_count") + end end diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb index 46421266d..8c8de154b 100644 --- a/app/models/poll_answer.rb +++ b/app/models/poll_answer.rb @@ -8,6 +8,8 @@ class PollAnswer < ActiveRecord::Base xml_attr :answer + self.include_root_in_json = false + def update_vote_counter self.vote_count = self.vote_count + 1 self.save! diff --git a/app/models/post.rb b/app/models/post.rb index b2eda3d06..0cbc9f07d 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -72,6 +72,9 @@ class Post < ActiveRecord::Base def address end + def poll + end + def self.excluding_blocks(user) people = user.blocks.map{|b| b.person_id} scope = scoped diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index fa179250a..7e0d4789d 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -35,6 +35,7 @@ class PostPresenter :root => root, :title => title, :address => @post.address, + :poll => @post.poll, :interactions => { :likes => [user_like].compact, diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index 0cf179ba4..ac6fd0bf8 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -172,3 +172,7 @@ en: reshared: "Reshared" comment: "Comment" home: "HOME" + + poll: + vote: "Vote" + result: "<%=votes%> votes so far" diff --git a/config/routes.rb b/config/routes.rb index 38405a721..39b66432e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,11 +31,15 @@ Diaspora::Application.routes.draw do get :interactions end + resources :poll_participations, :only => [:create] + resources :likes, :only => [:create, :destroy, :index ] resources :participations, :only => [:create, :destroy, :index] resources :comments, :only => [:new, :create, :destroy, :index] end + + get 'p/:id' => 'posts#show', :as => 'short_post' get 'posts/:id/iframe' => 'posts#iframe', :as => 'iframe' diff --git a/lib/federated/generator.rb b/lib/federated/generator.rb index 96fe9006c..ab6025ef2 100644 --- a/lib/federated/generator.rb +++ b/lib/federated/generator.rb @@ -11,8 +11,6 @@ module Federated FEDERATION_LOGGER.info("user:#{@user.id} dispatching #{relayable.class}:#{relayable.guid}") Postzord::Dispatcher.defer_build_and_post(@user, relayable) relayable - else - false end end