DG DC; Move stuff to second page of framer

This commit is contained in:
danielgrippi 2012-05-17 18:38:03 -07:00
parent 58e4c3614b
commit 62ba75ad1b
15 changed files with 141 additions and 134 deletions

View file

@ -11,9 +11,7 @@ app.pages.Composer = app.views.Base.extend({
},
formAttrs : {
"textarea#text_with_markup" : "text",
"input.aspect_ids" : "aspect_ids[]",
"input.services" : "services[]"
"textarea#text_with_markup" : "text"
},
initialize : function(){
@ -45,34 +43,13 @@ app.pages.Composer = app.views.Base.extend({
},
setModelAttributes : function(overrides){
var form = this.$el;
this.model.set(_.inject(this.formAttrs, setValueFromField, {}))
this.setFormAttrs()
this.model.photos = this.postForm.pictureForm.photos
this.model.set({"photos": this.model.photos.toJSON() })
this.model.set(overrides)
function setValueFromField(memo, attribute, selector){
if(attribute.slice("-2") === "[]") {
memo[attribute.slice(0, attribute.length - 2)] = _.pluck(form.find(selector).serializeArray(), "value")
} else {
memo[attribute] = form.find(selector).val();
}
return memo
}
}
});
app.views.ComposerControls = app.views.Base.extend({
templateName : 'composer-controls',
subviews : {
".aspect-selector" : "aspectsDropdown",
".service-selector" : "servicesSelector"
},
initialize : function() {
this.aspectsDropdown = new app.views.AspectsDropdown({model : this.model});
this.servicesSelector = new app.views.ServicesSelector({model : this.model});
}
templateName : 'composer-controls'
})

View file

@ -10,9 +10,10 @@ app.pages.Framer = app.views.Base.extend({
initialize : function(){
this.model = app.frame
this.model.authorIsCurrentUser = function(){ return true }
if(!this.model.get("frame_name")) this.model.setFrameName()
this.model.bind("change", this.render, this)
this.model.authorIsCurrentUser = function(){ return true }
this.model.bind("change:frame_name", this.render, this)
this.model.bind("sync", this.navigateNext, this)
this.framerControls = new app.views.framerControls({model : this.model})
@ -49,19 +50,43 @@ app.views.framerControls = app.views.Base.extend({
events : {
"click button.done" : "saveFrame",
"click button.back" : "editFrame"
"click button.back" : "editFrame",
"change input" : "setFormAttrs"
},
subviews : {
".template-picker" : 'templatePicker'
subviews:{
".template-picker":'templatePicker',
".aspect-selector":"aspectsDropdown",
".service-selector":"servicesSelector"
},
formAttrs : {
"input.mood:checked" : "frame_name",
"input.aspect_ids" : "aspect_ids[]",
"input.services" : "services[]"
},
initialize : function(){
this.templatePicker = new app.views.TemplatePicker({model: this.model})
this.aspectsDropdown = new app.views.AspectsDropdown({model:this.model});
this.servicesSelector = new app.views.ServicesSelector({model:this.model});
},
presenter : function() {
var selectedFrame = this.model.get("frame_name")
, templates =_.union(app.models.Post.frameMoods, _.without(app.models.Post.legacyTemplateNames, ["status", "status-with-photo-backdrop", "photo-backdrop", "activity-streams-photo", "note"])) //subtract re-implemented templates
return _.extend(this.defaultPresenter(), {
templates :_.map(templates, function(template) {
return {
name : template,
checked : selectedFrame === template
}
})
})
},
saveFrame : function(){
this.$('button').prop('disabled', 'disabled').addClass('disabled')
this.setFormAttrs()
this.model.save()
},

View file

@ -71,6 +71,20 @@ app.views.Base = Backbone.View.extend({
removeTooltips : function() {
$(".tooltip").remove();
},
setFormAttrs : function(){
this.model.set(_.inject(this.formAttrs, _.bind(setValueFromField, this), {}))
console.log("set from form", this.model.attributes)
function setValueFromField(memo, attribute, selector){
if(attribute.slice("-2") === "[]") {
memo[attribute.slice(0, attribute.length - 2)] = _.pluck(this.$el.find(selector).serializeArray(), "value")
} else {
memo[attribute] = this.$el.find(selector).val();
}
return memo
}
}
});

View file

@ -57,4 +57,4 @@ app.views.AspectsDropdown = app.views.Base.extend({
$.trim(this.$(".dropdown-toggle .text").text(text))
}
})
});

View file

@ -1,33 +0,0 @@
app.views.TemplatePicker = app.views.Base.extend({
templateName : "template-picker",
events : {
"click .mood" : "setModelTemplate"
},
initialize : function(){
if(!this.model.get('frame_name')) this.model.setFrameName()
},
postRenderTemplate : function(){
this.setSelectedMoodAttribute()
},
setModelTemplate : function(evt){
evt.preventDefault();
var selectedMood = $(evt.target);
this.model.set({"frame_name": selectedMood.data("mood")})
this.setSelectedMoodAttribute()
},
setSelectedMoodAttribute : function(){
this.$("#selected_mood").removeAttr("id")
this.$(".mood[data-mood=" + this.model.get("frame_name") + "]").attr("id", "selected_mood")
},
presenter : function() {
return _.extend(this.defaultPresenter(), {
templates : _.union(app.models.Post.frameMoods, _.without(app.models.Post.legacyTemplateNames, ["status", "status-with-photo-backdrop", "photo-backdrop", "activity-streams-photo", "note"])) //subtract re-implemented templates
})
}
})

View file

@ -53,6 +53,10 @@
.aspect-selector {
float: left;
form {
margin: 0
}
i, input {
display: none;
}
@ -65,6 +69,13 @@
}
label {
margin : 0;
padding : 5px 0;
&:hover {
background-color : #eee;
}
span:not(.caret) {
padding-left: 21px;
}
@ -80,23 +91,37 @@
text-align: left;
}
a.mood {
@include border-radius();
margin-right: 11px;
padding: 7px;
color: #999;
font-size: 14px;
line-height: 2em;
.template-picker {
margin-bottom : 1em;
&#selected_mood {
background-color: #222;
input {
display : none;
}
&:hover {
label {
@include transition(background-color);
@include border-radius();
cursor : pointer;
display: inline;
margin-right: 11px;
padding: 7px;
color: #999;
font-size: 14px;
line-height: 2em;
&:hover {
background-color: #222;
text-decoration: none;
}
}
input:checked + label {
background-color: #222;
text-decoration: none;
}
}
}
// this is about the service toggle icons, there is a jasmine test that tests this in service_selector spec

View file

@ -1,5 +1,3 @@
<div id='controls-wrapper'>
<button class="done btn btn-primary next">Next <i class="icon-arrow-right icon-white"></i></button>
<div class="aspect-selector"/>
<div class="service-selector"/>
</div>

View file

@ -1,5 +1,12 @@
<div id='controls-wrapper'>
<div class='template-picker'></div>
<div class='template-picker'>
{{#each templates}}
<input id='frame_name_{{name}}' name="frame_name" type="radio" class="mood" value={{name}} {{#if checked}}checked=checked{{/if}} />
<label for='frame_name_{{name}}'>{{name}}</label>
{{/each}}
</div>
<button id='back' class="back btn">Back</button>
<button id='done' class="done btn btn-success">Post <i class='icon-white icon-ok-sign'></i></button>
<div class="aspect-selector"/>
<div class="service-selector"/>
</div>

View file

@ -1,3 +0,0 @@
{{#each templates}}
<a class="mood" data-mood={{.}} href="#">{{.}}</a>
{{/each}}

View file

@ -54,5 +54,6 @@ Scenario: Resharing an nsfw post
And I wait for 2 seconds
And I wait for the ajax to finish
And I go to the home page
#if this is failing on travis throw a random wait in here :/
Then I should not see "Sexy Senators Gone Wild!"
And I should have 2 nsfw posts

View file

@ -118,7 +118,7 @@ Then /^I should see "([^"]*)" in the framer preview$/ do |post_text|
end
When /^I select the mood "([^"]*)"$/ do |mood|
click_link mood
find("label:contains('#{mood}')").click
end
Then /^the post's (?:default |)mood should (?:still |)be "([^"]*)"$/ do |mood|

View file

@ -7,9 +7,10 @@ Feature: Creating a new post
Scenario: Posting a public message with a photo
And I write "I love RMS"
When I select "Public" in my aspects dropdown
And I upload a fixture picture with filename "button.gif"
When I go through the default composer
When I start the framing process
When I select "Public" in my aspects dropdown
And I finalize my frame
When I go to "/stream"
Then I should see "I love RMS" as the first post in my stream
And "I love RMS" should be a public post in my stream
@ -17,8 +18,9 @@ Feature: Creating a new post
Scenario: Posting to Aspects
And I write "This is super skrunkle"
And I start the framing process
When I select "All Aspects" in my aspects dropdown
And I go through the default composer
And I finalize my frame
When I go to "/stream"
Then I should see "This is super skrunkle" as the first post in my stream
Then "This is super skrunkle" should be a limited post in my stream

View file

@ -21,17 +21,12 @@ describe("app.pages.Composer", function(){
describe(" setting the model's attributes from the various form fields", function(){
beforeEach(function(){
this.page.$("form .text").val("Oh My")
this.page.$("input.aspect_ids").val("public")
this.page.$("input.services[value=facebook]").attr("checked", "checked")
this.page.$("input.services[value=twitter]").attr("checked", "checked")
})
it("instantiates a post on form submit", function(){
this.page.$("button.next").click()
waitsFor(function(){ return this.navigateSpy.wasCalled })
runs(function(){
expect(this.page.model.get("aspect_ids")).toEqual(["public"])
expect(this.page.model.get("services")).toEqual(["facebook", "twitter"])
expect(this.page.model.get("text")).toBe("Oh My")
})
})

View file

@ -1,8 +1,11 @@
describe("app.pages.Framer", function(){
beforeEach(function(){
loginAs(factory.user())
app.frame = new factory.statusMessage();
app.frame = new factory.statusMessage({frame_name: undefined});
this.page = new app.pages.Framer();
this.model = this.page.model
expect(this.model).toBe(app.frame) //uses global state of app.frame :/
});
it("passes the model down to the post view", function(){
@ -19,6 +22,20 @@ describe("app.pages.Framer", function(){
// want a spec here for the bookmarklet case
})
describe("initialization", function(){
it("calls setFrameName on the model when there is no frame_name", function(){
spyOn(this.model, 'setFrameName')
this.model.unset("frame_name")
new app.pages.Framer()
expect(this.model.setFrameName).toHaveBeenCalled()
})
it("sets the frame_name of the model to 'Day' by default", function(){ //jasmine integration test, arguably unnecessary
expect(this.model.get("frame_name")).toBe("Day")
})
})
describe("rendering", function(){
beforeEach(function(){
this.page.render();
@ -30,10 +47,28 @@ describe("app.pages.Framer", function(){
expect(app.frame.save).toHaveBeenCalled();
});
it("makes and renders a new smallFrame when the template is changed", function(){
expect(app.frame.get("frame_name")).not.toBe("night") //pre conditions, yo
this.page.$("a.mood[data-mood=Night]").click()
expect(app.frame.get("frame_name")).toBe("Night")
})
describe("setting the model's attributes from the various form fields", function(){
beforeEach(function(){
this.page.$("input.mood").attr("checked", false) //radio button hax
expect(app.frame.get("frame_name")).not.toBe("Night")
this.page.$("input.aspect_ids").val("public")
this.page.$("input[value='Night']").attr("checked", "checked")
this.page.$("input.services[value=facebook]").attr("checked", "checked")
this.page.$("input.services[value=twitter]").attr("checked", "checked")
})
it("instantiates a post on form submit", function(){
this.page.$("input").trigger("change") //runs setFormAttrs
waitsFor(function(){
return this.page.model.get("frame_name") == "Night"
})
runs(function(){
expect(this.page.model.get("aspect_ids")).toEqual(["public"])
expect(this.page.model.get("services")).toEqual(["facebook", "twitter"])
expect(this.page.model.get("frame_name")).toBe("Night")
})
})
});
});
});

View file

@ -1,36 +0,0 @@
describe("app.views.TemplatePicker", function(){
beforeEach(function(){
this.model = factory.statusMessage({frame_name: undefined})
this.view = new app.views.TemplatePicker({model:this.model })
})
describe("initialization", function(){
it("calls setFrameName on the model when there is no frame_name", function(){
spyOn(this.model, 'setFrameName')
this.model.unset("frame_name")
new app.views.TemplatePicker({model:this.model})
expect(this.model.setFrameName).toHaveBeenCalled()
})
it("sets the frame_name of the model to 'Day' by default", function(){ //jasmine integration test, arguably unnecessary
expect(this.model.get("frame_name")).toBe("Day")
})
})
describe("rendering", function(){
beforeEach(function(){
this.model.set({frame_name : 'Wallpaper'})
this.view.render()
})
it("selects the model's frame_name from the dropdown", function(){
expect(this.view.$(".mood#selected_mood").data("mood")).toBe("Wallpaper")
})
it("changes the frame_name on the model when is is selected", function(){
this.view.$(".mood[data-mood=Night]").click()
expect(this.view.$(".mood#selected_mood").data("mood")).toBe("Night")
expect(this.model.get("frame_name")).toBe('Night')
})
})
})