From 6288eff5991087b695937863ca7e0b6823c709e3 Mon Sep 17 00:00:00 2001 From: Dennis Collinson <dennis.collective@gmail.com> Date: Mon, 26 Mar 2012 17:02:09 -0700 Subject: [PATCH] day mood for a post responds to content extract creating a post with templates to a static post view method. Legacy templates extracted, day view day mood shows photos and has variable text size --- features/step_definitions/trumpeter_steps.rb | 55 ++++++++++++------- features/trumpeter.feature | 15 +++-- public/javascripts/app/models/post.js | 15 +++++ public/javascripts/app/pages/framer.js | 18 +----- public/javascripts/app/pages/post-viewer.js | 9 +-- .../javascripts/app/templates/day.handlebars | 2 + .../app/templates/photo-viewer.handlebars | 3 + public/javascripts/app/views.js | 4 +- public/javascripts/app/views/photo_viewer.js | 7 +++ public/javascripts/app/views/post/day_view.js | 16 ++++++ public/javascripts/app/views/post_view.js | 31 +++++++++-- .../app/views/template_picker_view.js | 10 +--- public/stylesheets/sass/new-templates.scss | 4 ++ spec/javascripts/app/pages/framer_spec.js | 2 +- .../app/views/photo_viewer_spec.js | 19 +++++++ .../app/views/post/day_view_spec.js | 34 ++++++++++++ spec/javascripts/helpers/factory.js | 14 +++++ 17 files changed, 193 insertions(+), 65 deletions(-) create mode 100644 public/javascripts/app/templates/day.handlebars create mode 100644 public/javascripts/app/templates/photo-viewer.handlebars create mode 100644 public/javascripts/app/views/photo_viewer.js create mode 100644 public/javascripts/app/views/post/day_view.js create mode 100644 spec/javascripts/app/views/photo_viewer_spec.js create mode 100644 spec/javascripts/app/views/post/day_view_spec.js diff --git a/features/step_definitions/trumpeter_steps.rb b/features/step_definitions/trumpeter_steps.rb index b40f2beac8..56d58bc598 100644 --- a/features/step_definitions/trumpeter_steps.rb +++ b/features/step_definitions/trumpeter_steps.rb @@ -25,14 +25,29 @@ def finalize_frame click_button "done" end -def within_frame_preview - within find(".post") do - yield - end +def assert_post_renders_with(template_name) + find(".post")["data-template"].should == template_name.downcase end -def assert_post_renders_with(template_name) - find(".post")["data-template"].should == template_name +def find_image_by_filename(filename) + find("img[src='#{@image_sources[filename]}']") +end + +def store_image_filename(file_name) + @image_sources ||= {} + @image_sources[file_name] = all(".photos img").last["src"] + @image_sources[file_name].should be_present +end + +def upload_photo(file_name) + orig_photo_count = all(".photos img").size + + within ".new_photo" do + attach_file "photo[user_file]", Rails.root.join("spec", "fixtures", file_name) + wait_until { all(".photos img").size == orig_photo_count + 1 } + end + + store_image_filename(file_name) end When /^I trumpet$/ do @@ -60,21 +75,13 @@ Then /^"([^"]*)" should be a (limited|public) post in my stream$/ do |post_text, end When /^I upload a fixture picture with filename "([^"]*)"$/ do |file_name| - orig_photo_count = all(".photos img").size - - within ".new_photo" do - attach_file "photo[user_file]", Rails.root.join("spec", "fixtures", file_name) - wait_until { all(".photos img").size == orig_photo_count + 1 } - end - - @image_sources ||= {} - @image_sources[file_name] = all(".photos img").last["src"] - @image_sources[file_name].should be_present + upload_photo(file_name) end Then /^"([^"]*)" should have the "([^"]*)" picture$/ do |post_text, file_name| - image = find_post_by_text(post_text).find(".photo_attachments img[src='#{@image_sources[file_name]}']") - image.should be_present + within find_post_by_text(post_text) do + find_image_by_filename(file_name).should be_present + end end When /^I go through the default composer$/ do @@ -95,13 +102,19 @@ Then /^"([^"]*)" should have (\d+) pictures$/ do |post_text, number_of_pictures| end Then /^I should see "([^"]*)" in the framer preview$/ do |post_text| - within_frame_preview { page.should have_content(post_text) } + within(find(".post")) { page.should have_content(post_text) } end -When /^I select the template "([^"]*)"$/ do |template_name| +When /^I select the mood "([^"]*)"$/ do |template_name| select template_name, :from => 'template' end -Then /^the post should (?:still |)be rendered as a "([^"]*)"$/ do |template_name| +Then /^the post's mood should (?:still |)be "([^"]*)"$/ do |template_name| assert_post_renders_with(template_name) +end + +When /^"([^"]*)" should be in the post's picture viewer$/ do |file_name| + within(".photo_viewer") do + find_image_by_filename(file_name).should be_present + end end \ No newline at end of file diff --git a/features/trumpeter.feature b/features/trumpeter.feature index 29137f37d5..cbeb8a45cf 100644 --- a/features/trumpeter.feature +++ b/features/trumpeter.feature @@ -42,13 +42,18 @@ Feature: Creating a new post Scenario: Framing your frame When I write "This is hella customized" And I upload a fixture picture with filename "button.gif" + And I start the framing process Then I should see "This is hella customized" in the framer preview -# And I should see the image "button.gif" background - When I select the template "note" - Then the post should be rendered as a "note" + # Then the default mood for the post should be "Wallpaper" + # And I should see the image "button.gif" background + When I select the mood "Day" + Then the post's mood should be "Day" + And "button.gif" should be in the post's picture viewer + And I should see "This is hella customized" in the framer preview + When I finalize my frame And I go to "/stream" Then "This is hella customized" should be post 1 - When I click the show page link for "This is hella customized" - Then the post should still be rendered as a "note" + And I click the show page link for "This is hella customized" + And the post's mood should still be "Day" diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index a5beb5ecd3..efe9c9a8c6 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -90,4 +90,19 @@ app.models.Post = Backbone.Model.extend({ self.trigger('interacted', this) }}); } +}, { + + frameMoods : [ + "Day" + ], + + legacyTemplateNames : [ + "status-with-photo-backdrop", + "note", + "rich-media", + "multi-photo", + "photo-backdrop", + "activity-streams-photo", + "status" + ] }); diff --git a/public/javascripts/app/pages/framer.js b/public/javascripts/app/pages/framer.js index 3939f832fe..e75f3b1ac1 100644 --- a/public/javascripts/app/pages/framer.js +++ b/public/javascripts/app/pages/framer.js @@ -14,28 +14,14 @@ app.pages.Framer = app.views.Base.extend({ initialize : function(){ this.model = app.frame + this.model.authorIsCurrentUser = function(){ return true } this.model.bind("change", this.render, this) this.templatePicker = new app.views.TemplatePicker({ model: this.model }) }, postView : function(){ - //we might be leaky like cray cray with this - - var templateType = this.model.get("frame_name") - - this._postView = new app.views.Post({ - model : this.model, - className : templateType + " post loaded", - templateName : "post-viewer/content/" + templateType, - attributes : {"data-template" : templateType} - }); - - this._postView.feedbackView = new Backbone.View - - this.model.authorIsCurrentUser = function(){ return true } - - return this._postView + return app.views.Post.showFactory(this.model) }, saveFrame : function(){ diff --git a/public/javascripts/app/pages/post-viewer.js b/public/javascripts/app/pages/post-viewer.js index afea0ae7d8..803dbe384f 100644 --- a/public/javascripts/app/pages/post-viewer.js +++ b/public/javascripts/app/pages/post-viewer.js @@ -25,14 +25,7 @@ app.pages.PostViewer = app.views.Base.extend({ this.authorView = new app.views.PostViewerAuthor({ model : this.model }); this.interactionsView = new app.views.PostViewerInteractions({ model : this.model }); this.navView = new app.views.PostViewerNav({ model : this.model }); - - var frameName = this.model.get("frame_name") - this.postView = new app.views.Post({ - model : this.model, - className : frameName + " post loaded", - templateName : "post-viewer/content/" + frameName, - attributes : {"data-template" : frameName} - }); + this.postView = app.views.Post.showFactory(this.model) this.render(); }, diff --git a/public/javascripts/app/templates/day.handlebars b/public/javascripts/app/templates/day.handlebars new file mode 100644 index 0000000000..7a9acc3fc7 --- /dev/null +++ b/public/javascripts/app/templates/day.handlebars @@ -0,0 +1,2 @@ +<section class="text">{{{text}}}</section> +<section class="photo_viewer"></section> diff --git a/public/javascripts/app/templates/photo-viewer.handlebars b/public/javascripts/app/templates/photo-viewer.handlebars new file mode 100644 index 0000000000..1e83ff5d32 --- /dev/null +++ b/public/javascripts/app/templates/photo-viewer.handlebars @@ -0,0 +1,3 @@ +{{#each photos}} + <img src="{{sizes.large}}"/> +{{/each}} \ No newline at end of file diff --git a/public/javascripts/app/views.js b/public/javascripts/app/views.js index 6cd4f336e2..faadd32ce5 100644 --- a/public/javascripts/app/views.js +++ b/public/javascripts/app/views.js @@ -40,7 +40,9 @@ app.views.Base = Backbone.View.extend({ renderTemplate : function(){ var presenter = _.isFunction(this.presenter) ? this.presenter() : this.presenter this.template = JST[this.templateName] - $(this.el).html(this.template(presenter)); + $(this.el) + .html(this.template(presenter)) + .attr("data-template", _.last(this.templateName.split("/"))); this.postRenderTemplate(); }, diff --git a/public/javascripts/app/views/photo_viewer.js b/public/javascripts/app/views/photo_viewer.js new file mode 100644 index 0000000000..3f30cfbd46 --- /dev/null +++ b/public/javascripts/app/views/photo_viewer.js @@ -0,0 +1,7 @@ +app.views.PhotoViewer = app.views.Base.extend({ + templateName : "photo-viewer", + + presenter : function(){ + return { photos : this.model.get("photos") } //json array of attributes, not backbone models, yet. + } +}); \ No newline at end of file diff --git a/public/javascripts/app/views/post/day_view.js b/public/javascripts/app/views/post/day_view.js new file mode 100644 index 0000000000..f01bb41a9f --- /dev/null +++ b/public/javascripts/app/views/post/day_view.js @@ -0,0 +1,16 @@ +app.views.Post.Day = app.views.Post.extend({ + templateName : "day", + className : "day post loaded", + + subviews : { "section.photo_viewer" : "photoViewer" }, + + photoViewer : function(){ + return new app.views.PhotoViewer({ model : this.model }) + }, + + postRenderTemplate : function(){ + if(this.model.get("text").length < 140){ + this.$('section.text').addClass('headline'); + } + } +}); \ No newline at end of file diff --git a/public/javascripts/app/views/post_view.js b/public/javascripts/app/views/post_view.js index bc6345e505..4f167fd3ae 100644 --- a/public/javascripts/app/views/post_view.js +++ b/public/javascripts/app/views/post_view.js @@ -1,8 +1,4 @@ app.views.Post = app.views.StreamObject.extend({ - initialize : function(options) { - this.templateName = options.templateName - }, - presenter : function() { return _.extend(this.defaultPresenter(), { authorIsCurrentUser : this.authorIsCurrentUser(), @@ -18,4 +14,31 @@ app.views.Post = app.views.StreamObject.extend({ showPost : function() { return (app.currentUser.get("showNsfw")) || !this.model.get("nsfw") } +}, { //static methods below + + showFactory : function(model) { + var frameName = model.get("frame_name"); + + if(_.include(app.models.Post.legacyTemplateNames, frameName)){ + return legacyShow(model) + } else { + return new app.views.Post[frameName]({ + model : model + }) + } + + function legacyShow(model) { + return new app.views.Post.Legacy({ + model : model, + className : frameName + " post loaded", + templateName : "post-viewer/content/" + frameName + }); + } + } }); + +app.views.Post.Legacy = app.views.Post.extend({ + initialize : function(options) { + this.templateName = options.templateName || this.templateName + } +}) \ No newline at end of file diff --git a/public/javascripts/app/views/template_picker_view.js b/public/javascripts/app/views/template_picker_view.js index bada253387..834bd72e77 100644 --- a/public/javascripts/app/views/template_picker_view.js +++ b/public/javascripts/app/views/template_picker_view.js @@ -19,15 +19,7 @@ app.views.TemplatePicker = app.views.Base.extend({ presenter : function() { return _.extend(this.defaultPresenter(), { - templates : [ - "status-with-photo-backdrop", - "note", - "rich-media", - "multi-photo", - "photo-backdrop", - "activity-streams-photo", - "status" - ] + templates : _.union(app.models.Post.frameMoods, app.models.Post.legacyTemplateNames) }) } }) \ No newline at end of file diff --git a/public/stylesheets/sass/new-templates.scss b/public/stylesheets/sass/new-templates.scss index 3c7c22d7dd..c8ce383556 100644 --- a/public/stylesheets/sass/new-templates.scss +++ b/public/stylesheets/sass/new-templates.scss @@ -805,3 +805,7 @@ text-rendering: optimizelegibility; position: absolute; } } + +.headline p{ + @include media-text(); +} \ No newline at end of file diff --git a/spec/javascripts/app/pages/framer_spec.js b/spec/javascripts/app/pages/framer_spec.js index 951d3a92c3..db9deb0de4 100644 --- a/spec/javascripts/app/pages/framer_spec.js +++ b/spec/javascripts/app/pages/framer_spec.js @@ -10,7 +10,7 @@ describe("app.pages.Framer", function(){ }); it("passes the model down to the post view", function(){ - expect(this.page._postView.model).toBe(app.frame) + expect(this.page.postView().model).toBe(app.frame) }); describe("rendering", function(){ diff --git a/spec/javascripts/app/views/photo_viewer_spec.js b/spec/javascripts/app/views/photo_viewer_spec.js new file mode 100644 index 0000000000..6f25d580b6 --- /dev/null +++ b/spec/javascripts/app/views/photo_viewer_spec.js @@ -0,0 +1,19 @@ +describe("app.views.PhotoViewer", function(){ + beforeEach(function(){ + this.model = factory.post({ + photos : [ + factory.photoAttrs({sizes : {large : "http://tieguy.org/me.jpg"}}), + factory.photoAttrs({sizes : {large : "http://whatthefuckiselizabethstarkupto.com/none_knows.gif"}}) //SIC + ] + }) + this.view = new app.views.PhotoViewer({model : this.model}) + }) + + describe("rendering", function(){ + it("should have an image for each photoAttr on the model", function(){ + this.view.render() + expect(this.view.$("img").length).toBe(2) + expect(this.view.$("img[src='http://tieguy.org/me.jpg']")).toExist() + }) + }) +}) \ No newline at end of file diff --git a/spec/javascripts/app/views/post/day_view_spec.js b/spec/javascripts/app/views/post/day_view_spec.js new file mode 100644 index 0000000000..397ac46151 --- /dev/null +++ b/spec/javascripts/app/views/post/day_view_spec.js @@ -0,0 +1,34 @@ +describe("app.views.Post.Day", function(){ + beforeEach(function(){ + this.post = factory.post() + this.view = new app.views.Post.Day({model : this.post}) + }) + + describe("rendering", function(){ + it("is happy", function(){ + this.view.render() + }) + + describe("when the text is under 140 characters", function(){ + it("has class headline", function(){ + this.post.set({text : "Lol this is a short headline"}) + this.view.render() + expect(this.view.$("section.text")).toHaveClass("headline") + }) + }) + + describe("when the text is over 140 characters", function(){ + it("has doesn't have headline", function(){ + this.post.set({text :"Vegan bushwick tempor labore. Nulla seitan anim, aesthetic ex gluten-free viral" + + "thundercats street art. Occaecat carles deserunt lomo messenger bag wes anderson. Narwhal cray selvage " + + "dolor. Mixtape wes anderson american apparel, mustache readymade cred nulla squid veniam small batch id " + + "cupidatat. Pork belly high life consequat, raw denim sint terry richardson seitan single-origin coffee " + + "butcher. Sint yr fugiat cillum." + }) + + this.view.render() + expect(this.view.$("section.text")).not.toHaveClass("headline") + }) + }) + }) +}) \ No newline at end of file diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index 9262945e9e..b1ff242729 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -74,6 +74,20 @@ factory = { } }, + photoAttrs : function(overrides){ + return _.extend({ + author: factory.userAttrs(), + created_at: "2012-03-27T20:11:52Z", + guid: "8b0db16a4c4307b2", + id: 117, + sizes: { + large: "http://localhost:3000/uploads/images/scaled_full_d85410bd19db1016894c.jpg", + medium: "http://localhost:3000/uploads/images/thumb_medium_d85410bd19db1016894c.jpg", + small: "http://localhost:3000/uploads/images/thumb_small_d85410bd19db1016894c.jpg" + } + }, overrides) + }, + post : function(overrides) { defaultAttrs = _.extend(factory.postAttrs(), {"author" : this.author()}) return new app.models.Post(_.extend(defaultAttrs, overrides)) -- GitLab