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}}
+
+{{/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