diff --git a/app/assets/javascripts/app/views/publisher_view.js b/app/assets/javascripts/app/views/publisher_view.js index 675f4d4fdf8212599983f1d33c83e617ad23cacf..791992ef2b9094ae58f0e3a9353e95e5f8ccbd9f 100644 --- a/app/assets/javascripts/app/views/publisher_view.js +++ b/app/assets/javascripts/app/views/publisher_view.js @@ -23,6 +23,9 @@ app.views.Publisher = Backbone.View.extend({ "click .post_preview_button" : "createPostPreview", "textchange #status_message_fake_text": "handleTextchange", "click #locator" : "showLocation", + "click #poll_creator" : "showPollCreator", + "click #add_poll_answer" : "addPollAnswer", + "click .remove_poll_answer" : "removePollAnswer", "click #hide_location" : "destroyLocation", "keypress #location_address" : "avoidEnter" }, @@ -37,6 +40,8 @@ app.views.Publisher = Backbone.View.extend({ this.el_submit = this.$('input[type=submit], button#submit'); this.el_preview = this.$('button.post_preview_button'); this.el_photozone = this.$('#photodropzone'); + this.el_poll_creator = this.$('#poll_creator_wrapper'); + this.el_poll_answer = this.$('#poll_creator_wrapper .poll_answer'); // init mentions plugin Mentions.initialize(this.el_input); @@ -127,7 +132,6 @@ app.views.Publisher = Backbone.View.extend({ // lulz this code should be killed. var statusMessage = new app.models.Post(); - statusMessage.save({ "status_message" : { "text" : serializedForm["status_message[text]"] @@ -136,10 +140,12 @@ app.views.Publisher = Backbone.View.extend({ "photos" : serializedForm["photos[]"], "services" : serializedForm["services[]"], "location_address" : $("#location_address").val(), - "location_coords" : serializedForm["location[coords]"] + "location_coords" : serializedForm["location[coords]"], + "poll_question" : serializedForm["poll_question"] }, { url : "/status_messages", success : function() { + console.log(statusMessage); if(app.publisher) { $(app.publisher.el).trigger('ajax:success'); } @@ -171,6 +177,23 @@ app.views.Publisher = Backbone.View.extend({ } }, + showPollCreator: function(){ + this.el_poll_creator.toggle(); + }, + + addPollAnswer: function(){ + var clone = this.el_poll_answer.clone(); + var count_of_answers = this.el_poll_answer.size()+1; + clone.attr("name", "poll_answer_"+count_of_answers) + this.el_poll_answer.last().after(clone); + }, + + removePollAnswer: function(evt){ + if($(".poll_answer_input").size() > 1) { + $(evt.target).parent().remove(); + } + return false; + }, // avoid submitting form when pressing Enter key avoidEnter: function(evt){ if(evt.keyCode == 13) @@ -323,7 +346,7 @@ app.views.Publisher = Backbone.View.extend({ $(this.el).addClass("closed"); this.el_wrapper.removeClass("active"); this.el_input.css('height', ''); - + this.el_poll_creator.hide(); return this; }, diff --git a/app/assets/stylesheets/publisher.css.scss b/app/assets/stylesheets/publisher.css.scss index 0fe934716c7774227d67f380558688f9ba28ab7d..08ff3cec0dc8e932181072e119d42d853b8157d4 100644 --- a/app/assets/stylesheets/publisher.css.scss +++ b/app/assets/stylesheets/publisher.css.scss @@ -59,6 +59,7 @@ resize: none; height: 50px; } + } &.active textarea { min-height: 70px; @@ -78,6 +79,7 @@ line-height: 20px !important; width: 100% !important; } + } &.with_attachments .row-fluid#photodropzone_container { border-top: 1px dashed $border-grey; @@ -162,6 +164,7 @@ margin-right: 5px; #file-upload, #locator, + #poll_creator, #hide_location { text-decoration: none !important; font-size: 16px; @@ -215,3 +218,4 @@ } } } + diff --git a/app/assets/stylesheets/publisher_blueprint.css.scss b/app/assets/stylesheets/publisher_blueprint.css.scss index 23e3a94cada3d68a1b6d1ca7583c4d662d8ce680..68a6f617f63e4f6242d17b84000635cf1a2cb6f6 100644 --- a/app/assets/stylesheets/publisher_blueprint.css.scss +++ b/app/assets/stylesheets/publisher_blueprint.css.scss @@ -309,8 +309,25 @@ } } } + #poll_creator { + @extend #locator; + right: 50px; + } + .btn { height: 19px; width: 19px; } } + +#poll_creator_wrapper { + display:none; +} + +.remove_poll_answer { + display:inline-block; +} + +.poll_answer_input { + display:inline-block !important; +} \ No newline at end of file diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index 83f92f3ac8f4afa38593ede3465193b5aa945a2e..78507fc81c2ece34caf1787ee1a9b25f54971046 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -49,6 +49,11 @@ 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? + + #save all answers for poll + + @status_message.attach_photos_by_ids(params[:photos]) if @status_message.save diff --git a/app/models/poll.rb b/app/models/poll.rb new file mode 100644 index 0000000000000000000000000000000000000000..15d770cc45efeed719369ffbf617e91df852e6fb --- /dev/null +++ b/app/models/poll.rb @@ -0,0 +1,7 @@ +class Poll < ActiveRecord::Base + attr_accessible :question + + belongs_to :status_message + belongs_to :author, :class_name => :person, :foreign_key => :author_id + #has_many :poll_answers +end diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 4e0dfd127fe6d005f4930f6d3ac949a5a19036e1..352e646b2d4a03395933b53f6a7552497d86a07e 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -24,6 +24,7 @@ class StatusMessage < Post has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid has_one :location + has_one :poll # a StatusMessage is federated before its photos are so presence_of_content() fails erroneously if no text is present # therefore, we put the validation in a before_destory callback instead of a validation diff --git a/app/views/publisher/_publisher_blueprint.html.haml b/app/views/publisher/_publisher_blueprint.html.haml index b99d55958b0565a6451b1bf4216e47292dca89de..0d4357cc00c2b3d93d6fea55183a1434b203dc98 100644 --- a/app/views/publisher/_publisher_blueprint.html.haml +++ b/app/views/publisher/_publisher_blueprint.html.haml @@ -28,12 +28,25 @@ %span#publisher-images %span.markdownIndications != t('shared.publisher.formatWithMarkdown', markdown_link: link_to(t('help.markdown'), 'https://diasporafoundation.org/formatting', target: :blank)) + #poll_creator.btn{:title => t('.create_poll')} + = image_tag 'icons/marker.png', :alt => t('.create_poll').titleize, :class => 'publisher_image' #locator.btn{:title => t('shared.publisher.get_location')} = image_tag 'icons/marker.png', :alt => t('shared.publisher.get_location').titleize, :class => 'publisher_image' #file-upload.btn{:title => t('shared.publisher.upload_photos')} = image_tag 'icons/camera.png', :alt => t('shared.publisher.upload_photos').titleize, :class => 'publisher_image' = hidden_field :location, :coords #location_container + #poll_creator_wrapper + = 'Poll creation' + %br + %br + %input{:id => 'poll_question', :placeholder => 'Question', :name => 'poll_question'} + %div{:class => 'poll_answer'} + %input{:class => 'poll_answer_input', :placeholder => 'Answer', :name => 'poll_answer_1'} + %a{:class => 'remove_poll_answer'} + = t('shared.publisher.poll.remove_poll_answer') + %div{:id => 'add_poll_answer', :class => 'button creation'} + = t('shared.publisher.poll.add_poll_answer') - if publisher_public = hidden_field_tag 'aspect_ids[]', "public" diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 08424ab0c514b5ec6cde32a41c3a5ead57e1cd54..5e9fa2e9d4aa74e8ffd4c569f21f95ca283fe36f 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -1037,6 +1037,9 @@ en: hello: "Hey everyone, I'm #%{new_user_tag}. " i_like: "I'm interested in %{tags}. " invited_by: "Thanks for the invite, " + poll: + remove_poll_answer: "Remove answer" + add_poll_answer: "Add answer" add_contact: enter_a_diaspora_username: "Enter a diaspora* username:" your_diaspora_username_is: "Your diaspora* username is: %{diaspora_handle}" diff --git a/db/migrate/20140308154022_create_polls.rb b/db/migrate/20140308154022_create_polls.rb new file mode 100644 index 0000000000000000000000000000000000000000..4fd4479745e359a333f9d55db3f53b327e66e020 --- /dev/null +++ b/db/migrate/20140308154022_create_polls.rb @@ -0,0 +1,33 @@ +class CreatePolls < ActiveRecord::Migration + def up + create_table :polls do |t| + t.string :question, :null => false + t.belongs_to :status_message, :null => false + t.boolean :status + t.timestamps + end + add_index :polls, :status_message_id + + create_table :poll_answers do |t| + t.string :answer, :null => false + t.belongs_to :poll, :null => false + end + add_index :poll_answers, :poll_id + + create_table :poll_participations do |t| + t.belongs_to :poll_answer, :null => false + t.belongs_to :author, :null => false + t.belongs_to :poll, :null => false + t.datetime :time + + t.timestamps + end + add_index :poll_participations, :poll_id + end + + def down + drop_table :polls + drop_table :poll_answers + drop_table :poll_participations + end +end diff --git a/db/schema.rb b/db/schema.rb index 60fab83be6cd9654558e1db72713f0c23998771a..fe5a33e0482d1f956e31b1f36bb6e26188d7c89a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20140222162826) do +ActiveRecord::Schema.define(:version => 20140308154022) do create_table "account_deletions", :force => true do |t| t.string "diaspora_handle" @@ -283,6 +283,34 @@ ActiveRecord::Schema.define(:version => 20140222162826) do t.datetime "updated_at", :null => false end + create_table "poll_answers", :force => true do |t| + t.string "answer", :null => false + t.integer "poll_id", :null => false + end + + add_index "poll_answers", ["poll_id"], :name => "index_poll_answers_on_poll_id" + + create_table "poll_participations", :force => true do |t| + t.integer "poll_answer_id", :null => false + t.integer "author_id", :null => false + t.integer "poll_id", :null => false + t.datetime "time" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "poll_participations", ["poll_id"], :name => "index_poll_participations_on_poll_id" + + create_table "polls", :force => true do |t| + t.string "question", :null => false + t.integer "status_message_id", :null => false + t.boolean "status" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "polls", ["status_message_id"], :name => "index_polls_on_status_message_id" + create_table "post_reports", :force => true do |t| t.integer "post_id", :null => false t.string "user_id" @@ -502,36 +530,36 @@ ActiveRecord::Schema.define(:version => 20140222162826) do add_index "users", ["invitation_token"], :name => "index_users_on_invitation_token" add_index "users", ["username"], :name => "index_users_on_username", :unique => true - add_foreign_key "aspect_memberships", "aspects", :name => "aspect_memberships_aspect_id_fk", :dependent => :delete - add_foreign_key "aspect_memberships", "contacts", :name => "aspect_memberships_contact_id_fk", :dependent => :delete + add_foreign_key "aspect_memberships", "aspects", name: "aspect_memberships_aspect_id_fk", dependent: :delete + add_foreign_key "aspect_memberships", "contacts", name: "aspect_memberships_contact_id_fk", dependent: :delete - add_foreign_key "aspect_visibilities", "aspects", :name => "aspect_visibilities_aspect_id_fk", :dependent => :delete + add_foreign_key "aspect_visibilities", "aspects", name: "aspect_visibilities_aspect_id_fk", dependent: :delete - add_foreign_key "comments", "people", :name => "comments_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "comments", "people", name: "comments_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete + add_foreign_key "contacts", "people", name: "contacts_person_id_fk", dependent: :delete - add_foreign_key "conversation_visibilities", "conversations", :name => "conversation_visibilities_conversation_id_fk", :dependent => :delete - add_foreign_key "conversation_visibilities", "people", :name => "conversation_visibilities_person_id_fk", :dependent => :delete + add_foreign_key "conversation_visibilities", "conversations", name: "conversation_visibilities_conversation_id_fk", dependent: :delete + add_foreign_key "conversation_visibilities", "people", name: "conversation_visibilities_person_id_fk", dependent: :delete - add_foreign_key "conversations", "people", :name => "conversations_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "conversations", "people", name: "conversations_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "invitations", "users", :name => "invitations_recipient_id_fk", :column => "recipient_id", :dependent => :delete - add_foreign_key "invitations", "users", :name => "invitations_sender_id_fk", :column => "sender_id", :dependent => :delete + add_foreign_key "invitations", "users", name: "invitations_recipient_id_fk", column: "recipient_id", dependent: :delete + add_foreign_key "invitations", "users", name: "invitations_sender_id_fk", column: "sender_id", dependent: :delete - add_foreign_key "likes", "people", :name => "likes_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "likes", "people", name: "likes_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "messages", "conversations", :name => "messages_conversation_id_fk", :dependent => :delete - add_foreign_key "messages", "people", :name => "messages_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "messages", "conversations", name: "messages_conversation_id_fk", dependent: :delete + add_foreign_key "messages", "people", name: "messages_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "notification_actors", "notifications", :name => "notification_actors_notification_id_fk", :dependent => :delete + add_foreign_key "notification_actors", "notifications", name: "notification_actors_notification_id_fk", dependent: :delete - add_foreign_key "posts", "people", :name => "posts_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "posts", "people", name: "posts_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "profiles", "people", :name => "profiles_person_id_fk", :dependent => :delete + add_foreign_key "profiles", "people", name: "profiles_person_id_fk", dependent: :delete - add_foreign_key "services", "users", :name => "services_user_id_fk", :dependent => :delete + add_foreign_key "services", "users", name: "services_user_id_fk", dependent: :delete - add_foreign_key "share_visibilities", "contacts", :name => "post_visibilities_contact_id_fk", :dependent => :delete + add_foreign_key "share_visibilities", "contacts", name: "post_visibilities_contact_id_fk", dependent: :delete end diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..8f2cabf75796f108ed698211b5bd29ccca6e9be1 --- /dev/null +++ b/spec/models/poll_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Poll do + pending "add some examples to (or delete) #{__FILE__}" +end