diff --git a/Changelog.md b/Changelog.md index cfba5e566..005785678 100644 --- a/Changelog.md +++ b/Changelog.md @@ -41,7 +41,7 @@ * Added comment count to statistic to enable calculations of posts/comments ratios [#4799](https://github.com/diaspora/diaspora/pull/4799) * Add filters to notifications controller [#4814](https://github.com/diaspora/diaspora/pull/4814) * Activate hovercards in SPV and conversations [#4870](https://github.com/diaspora/diaspora/pull/4870) -* Added possibility to conduct polls [#4861](https://github.com/diaspora/diaspora/pull/4861) +* Added possibility to conduct polls [#4861](https://github.com/diaspora/diaspora/pull/4861) [#4894](https://github.com/diaspora/diaspora/pull/4894) # 0.3.0.3 diff --git a/app/assets/javascripts/app/models/poll_participation.js b/app/assets/javascripts/app/models/poll_participation.js index a31c35779..36b560dbe 100644 --- a/app/assets/javascripts/app/models/poll_participation.js +++ b/app/assets/javascripts/app/models/poll_participation.js @@ -1,5 +1,5 @@ app.models.PollParticipation = Backbone.Model.extend({ - url : function(){ - "/poll_participations" + urlRoot: function(){ + return '/posts/' + this.get('post_id') + "/poll_participations"; } -}); \ No newline at end of file +}); diff --git a/app/assets/javascripts/app/views/poll_blueprint_view.js b/app/assets/javascripts/app/views/poll_blueprint_view.js new file mode 100644 index 000000000..ffb996961 --- /dev/null +++ b/app/assets/javascripts/app/views/poll_blueprint_view.js @@ -0,0 +1,17 @@ +//= require ./poll_view +app.views.PollBlueprint = app.views.Poll.extend({ + templateName: 'poll_blueprint', + + initialize: function(options) { + this.constructor.__super__.initialize.apply(this, options); + this.progressBarFactor = 3; + }, + setProgressBarData: function(progressBar, percent) { + progressBar.css('width', percent * this.progressBarFactor + 'px'); + progressBar.parent().next().html(" - " + percent + "%"); + }, + toggleElements: function() { + this.$('.poll_progress_bar_wrapper').toggle(); + this.$('.percentage').toggle(); + } +}); diff --git a/app/assets/javascripts/app/views/poll_view.js b/app/assets/javascripts/app/views/poll_view.js index 9a1df2a88..5b41f548c 100644 --- a/app/assets/javascripts/app/views/poll_view.js +++ b/app/assets/javascripts/app/views/poll_view.js @@ -1,94 +1,86 @@ app.views.Poll = app.views.Base.extend({ - templateName : "poll", + templateName: "poll", - events : { - "click .submit" : "vote", + events: { + "click .submit" : "clickSubmit", "click .toggle_result" : "toggleResult" }, - initialize : function(options) { + initialize: function(options) { + this.model.bind('change', this.render, this); + }, + + postRenderTemplate: function() { this.poll = this.model.attributes.poll; - this.progressBarFactor = 3; - this.toggleMode = 0; - }, - - postRenderTemplate : function() { - if(this.poll) { - this.setProgressBar(); - } - }, - - removeForm : function() { - var cnt = this.$("form").contents(); - this.$("form").replaceWith(cnt); - this.$('input').remove(); - this.$('submit').remove(); - this.$('.toggle_result_wrapper').remove(); - }, - - 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 = Math.round(answers[index].vote_count / this.poll.participation_count * 100); - } - var progressBar = this.$(".poll_progress_bar[data-answerid="+answers[index].id+"]"); - progressBar.parent().next().html(" - " + percentage + "%"); - var width = percentage * this.progressBarFactor; - progressBar.css("width", width + "px"); - } - }, - - toggleResult : function(e) { - this.$('.poll_progress_bar_wrapper').toggle(); - this.$('.percentage').toggle(); - if(this.toggleMode == 0) { - this.$('.toggle_result').html(Diaspora.I18n.t("poll.close_result")); - this.toggleMode = 1; - }else{ - this.$('.toggle_result').html(Diaspora.I18n.t("poll.show_result")); - this.toggleMode = 0; - } - return false; - }, - - refreshResult : function(answerId) { - this.updateCounter(answerId); this.setProgressBar(); }, - updateCounter : function(answerId) { - this.poll.participation_count++; - this.$('.poll_statistic').html(Diaspora.I18n.t("poll.count", {"count" : this.poll.participation_count})); + setProgressBar: function() { + if(!this.poll) return; + var answers = this.poll.poll_answers; - for(index = 0; index < answers.length; ++index) { - if(answers[index].id == answerId) { - answers[index].vote_count++; - return; + var participation_count = this.poll.participation_count; + var _this = this; + + _.each(answers, function(answer){ + var percent = 0; + if(participation_count > 0) { + percent = Math.round(answer.vote_count / participation_count * 100); } + + var progressBar = _this.$(".poll_progress_bar[data-answerid="+answer.id+"]"); + + _this.setProgressBarData(progressBar, percent); + }); + }, + + setProgressBarData: function(progressBar, percent) { + progressBar.css("width", percent + "%"); + progressBar.parents('.result-row').find('.percentage').text(percent + "%"); + }, + + toggleResult: function(evt) { + if(evt) evt.preventDefault(); + + this.toggleElements(); + + var toggle_result = this.$('.toggle_result'); + + if(!this.toggleMode) { + toggle_result.html(Diaspora.I18n.t("poll.close_result")); + this.toggleMode = 1; + } + else { + toggle_result.html(Diaspora.I18n.t("poll.show_result")); + this.toggleMode = 0; } }, - vote : function(evt){ - var result = parseInt($(evt.target).parent().find("input[name=vote]:checked").val()); - var pollParticipation = new app.models.PollParticipation(); - var parent = this; - pollParticipation.save({ - "poll_answer_id" : result, - "poll_id" : this.poll.poll_id - },{ - url : "/posts/"+this.poll.post_id+"/poll_participations", - success : function(model, response) { - parent.removeForm(); - parent.refreshResult(result); - if(parent.toggleMode == 0) { - parent.toggleResult(null); - } + toggleElements: function() { + this.$('.percentage').toggle(); + this.$('.progress').toggle(); + }, + clickSubmit: function(evt) { + evt.preventDefault(); + + var answer_id = parseInt($(evt.target).parent().find("input[name=vote]:checked").val()); + this.vote(answer_id); + }, + + vote: function(answer_id){ + var pollParticipation = new app.models.PollParticipation({ + poll_answer_id: answer_id, + poll_id: this.poll.poll_id, + post_id: this.poll.post_id, + }); + var _this = this; + + pollParticipation.save({},{ + success : function() { + _this.model.fetch(); } }); - return false; } -}); \ No newline at end of file +}); diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js index 19545b84e..2bd252781 100644 --- a/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js +++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_content_view.js @@ -7,7 +7,8 @@ app.views.SinglePostContent = app.views.Base.extend({ '#real-post-content' : 'postContentView', ".oembed" : "oEmbedView", ".opengraph" : "openGraphView", - ".status-message-location" : "postLocationStreamView" + ".status-message-location" : "postLocationStreamView", + '.poll': 'pollView', }, initialize : function() { @@ -15,6 +16,7 @@ app.views.SinglePostContent = app.views.Base.extend({ this.oEmbedView = new app.views.OEmbed({model : this.model}); this.openGraphView = new app.views.OpenGraph({model : this.model}); this.postContentView = new app.views.ExpandedStatusMessage({model: this.model}); + this.pollView = new app.views.Poll({ model: this.model }); }, postLocationStreamView : function(){ diff --git a/app/assets/javascripts/app/views/stream_post_views.js b/app/assets/javascripts/app/views/stream_post_views.js index fb1d846d4..5088784bc 100644 --- a/app/assets/javascripts/app/views/stream_post_views.js +++ b/app/assets/javascripts/app/views/stream_post_views.js @@ -32,7 +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}); + this.pollView = new app.views.PollBlueprint({model : this.model}); }, diff --git a/app/assets/stylesheets/new-templates.css.scss b/app/assets/stylesheets/new-templates.css.scss index 3219e81fa..cfc3795e4 100644 --- a/app/assets/stylesheets/new-templates.css.scss +++ b/app/assets/stylesheets/new-templates.css.scss @@ -27,6 +27,7 @@ @import 'bootstrap-headerfix'; @import 'opengraph'; @import 'single-post-view'; +@import 'new_styles/poll'; /* conversations */ @import 'conversations'; diff --git a/app/assets/stylesheets/new_styles/_poll.scss b/app/assets/stylesheets/new_styles/_poll.scss new file mode 100644 index 000000000..1f2fc69c5 --- /dev/null +++ b/app/assets/stylesheets/new_styles/_poll.scss @@ -0,0 +1,35 @@ +@import '../colors'; +@import '../mixins'; +@import 'new_mixins'; + +.poll_form { + border-top: 1px solid $border-grey; + border-bottom: 1px solid $border-grey; + margin: 10px 0px 10px 0px; + padding: 10px 0px 5px 0px; + + .poll_content { + margin-top: 5px; + } + .toggle_result_wrapper { + display: inline-block; + margin-top: 10px; + } + form { + margin-bottom: 0px; + } + + .progress { + background-image: none; + @include box-shadow(0, 0, 0); + margin-bottom: 5px; + height: 10px !important; + + .bar { + background-image: none; + background-color: $border-dark-grey; + color: $text-dark-grey; + text-align: left; + } + } +} diff --git a/app/assets/templates/poll_blueprint_tpl.jst.hbs b/app/assets/templates/poll_blueprint_tpl.jst.hbs new file mode 100644 index 000000000..ed9e18e7c --- /dev/null +++ b/app/assets/templates/poll_blueprint_tpl.jst.hbs @@ -0,0 +1,32 @@ +{{#if poll}} +
+

{{t "poll.count" count=poll.participation_count}}

+ {{poll.question}}
+ {{#unless already_participated_in_poll}} +
+ {{#poll.poll_answers}} + + + {{answer}} + +
+ {{/poll.poll_answers}} + +
+

+
{{t "poll.show_result"}}
+

+ {{else}} + {{#poll.poll_answers}} +
+
+
+ {{answer}} +

+
+ {{/poll.poll_answers}} + {{/unless}} +
+{{/if}} \ No newline at end of file diff --git a/app/assets/templates/poll_tpl.jst.hbs b/app/assets/templates/poll_tpl.jst.hbs index ed9e18e7c..6984a493d 100644 --- a/app/assets/templates/poll_tpl.jst.hbs +++ b/app/assets/templates/poll_tpl.jst.hbs @@ -1,32 +1,42 @@ {{#if poll}}
-

{{t "poll.count" count=poll.participation_count}}

- {{poll.question}}
- {{#unless already_participated_in_poll}} -
- {{#poll.poll_answers}} - -
-{{/if}} \ No newline at end of file +{{/if}} diff --git a/features/desktop/post_with_a_poll.feature b/features/desktop/post_with_a_poll.feature index 5d8b7b277..faed7efdd 100644 --- a/features/desktop/post_with_a_poll.feature +++ b/features/desktop/post_with_a_poll.feature @@ -62,4 +62,18 @@ Feature: posting with a poll And I press "Vote" within ".stream_element" Then I should see an element ".poll_progress_bar" And I should see an element ".percentage" - And I should see "1 vote so far" within ".poll_statistic" \ No newline at end of file + And I should see "1 vote so far" within ".poll_statistic" + + Scenario: click to show result + Given I expand the publisher + And I press the element "#poll_creator" + When I fill in the following: + | status_message_fake_text | I am eating yogurt | + | poll_question | What kind of yogurt do you like? | + And I fill in the following for the options: + | normal | + | not normal | + And I press "Share" + + And I press the element ".toggle_result" + Then I should see an element ".percentage" diff --git a/features/step_definitions/post_with_poll_steps.rb b/features/step_definitions/post_with_poll_steps.rb index 2ae5a78ba..e2ea6631a 100644 --- a/features/step_definitions/post_with_poll_steps.rb +++ b/features/step_definitions/post_with_poll_steps.rb @@ -19,14 +19,15 @@ When /^I fill in the following for the options:$/ do |table| end When /^I check the first option$/ do - sleep 1 + page.should have_css('.poll_form input') first(".poll_form input").click end And /^I press the element "([^"]*)"$/ do |selector| + page.should have_css(selector) find(selector).click end Then /^I should see an element "([^"]*)"$/ do |selector| page.should have_css(selector) -end \ No newline at end of file +end diff --git a/spec/javascripts/app/views/poll_view_spec.js b/spec/javascripts/app/views/poll_blueprint_view_spec.js similarity index 58% rename from spec/javascripts/app/views/poll_view_spec.js rename to spec/javascripts/app/views/poll_blueprint_view_spec.js index 4ee1a2ef8..acac4e1b6 100644 --- a/spec/javascripts/app/views/poll_view_spec.js +++ b/spec/javascripts/app/views/poll_blueprint_view_spec.js @@ -1,7 +1,7 @@ -describe("app.views.Poll", function(){ +describe("app.views.PollBlueprint", function(){ beforeEach(function() { loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); - this.view = new app.views.Poll({ "model" : factory.postWithPoll()}); + this.view = new app.views.PollBlueprint({ model: factory.postWithPoll()}); this.view.render(); }); @@ -21,25 +21,17 @@ describe("app.views.Poll", function(){ }) }); - describe("updateCounter", function(){ - it("updates the counter after a vote", function(){ - var pc = this.view.poll.participation_count; - var answerCount = this.view.poll.poll_answers[0].vote_count; - this.view.updateCounter(1); - expect(this.view.poll.participation_count).toBe(pc+1); - expect(this.view.poll.poll_answers[0].vote_count).toBe(answerCount+1); - }) - }); - describe("vote", function(){ it("checks the ajax call for voting", function(){ spyOn($, "ajax"); - var radio = this.view.$('input[name="vote"]:first'); - radio.attr('checked', true); - this.view.vote({'target' : radio}); + var answer = this.view.poll.poll_answers[0]; + var poll = this.view.poll; + + this.view.vote(answer.id); + var obj = JSON.parse($.ajax.mostRecentCall.args[0].data); - expect(obj.poll_id).toBe(this.view.poll.poll_id); - expect(obj.poll_answer_id).toBe(this.view.poll.poll_answers[0].id); + expect(obj.poll_id).toBe(poll.poll_id); + expect(obj.poll_answer_id).toBe(answer.id); }) }) });