Jamie Cai DC message in profile when user has no posts

This commit is contained in:
Dennis Collinson 2012-05-07 15:56:09 -07:00
parent fcd67ebc77
commit 1c135b61fd
10 changed files with 154 additions and 259 deletions

View file

@ -2,6 +2,14 @@ app.models.Profile = Backbone.Model.extend({
urlRoot : "/profiles"
}, {
preloadOrFetch : function(id){
if(app.hasPreload("person")) {
return new app.models.Profile(app.parsePreload("person"))
} else {
return this.findByGuid(id)
}
},
findByGuid : function(personId){
var person = new app.models.Profile({ id : personId})
person.fetch()

View file

@ -2,10 +2,8 @@
//= require ../views/profile_info_view
app.pages.Profile = app.views.Base.extend({
id : "profile",
templateName : "profile",
id : "profile",
subviews : {
"#profile-info" : "profileInfo",
@ -23,20 +21,10 @@ app.pages.Profile = app.views.Base.extend({
personGUID : null,
editMode : false,
presenter : function(){
var bio = this.model.get("bio") || ''
return _.extend(this.defaultPresenter(),
{text : this.model && app.helpers.textFormatter(bio, this.model),
isOwnProfile : this.isOwnProfile(),
showFollowButton : this.showFollowButton()
})
},
initialize : function(options) {
this.personGUID = options.personId
this.model = new app.models.Profile.findByGuid(options.personId)
this.model = this.model || app.models.Profile.preloadOrFetch(this.personGUID)
this.stream = options && options.stream || new app.models.Stream()
this.model.bind("change", this.setPageTitleAndBackground, this)
@ -54,6 +42,16 @@ app.pages.Profile = app.views.Base.extend({
this.profileInfo = new app.views.ProfileInfo({ model : this.model.set({isOwnProfile : this.isOwnProfile()}) })
},
presenter : function(){
var bio = this.model.get("bio") || ''
return _.extend(this.defaultPresenter(),
{text : this.model && app.helpers.textFormatter(bio, this.model),
isOwnProfile : this.isOwnProfile(),
showFollowButton : this.showFollowButton()
})
},
pulsateNewPostControl : function() {
this.$("#composer-button")[
this.stream.items.length == 0
@ -92,4 +90,4 @@ app.pages.Profile = app.views.Base.extend({
isOwnProfile : function() {
return(app.currentUser.get("guid") == this.personGUID)
}
});
});

View file

@ -10,9 +10,23 @@ app.views.Canvas = app.views.Base.extend(_.extend({}, app.views.infiniteScrollMi
renderTemplate : function() {
this.$el.empty()
this.stream.items.each(_.bind(function(post){
this.$el.append(this.createPostView(post).render().el);
}, this))
if(this.stream.items.isEmpty()){
var message
, person = app.page.model
if(person.get("is_own_profile")){
message = "Make something to start the magic."
} else {
var name = person.get("full_name") || ""
message = name + " hasn't posted anything yet."
}
this.$el.html("<p class='no-post-message'>" + message + "</p>")
} else {
this.stream.items.each(_.bind(function(post){
this.$el.append(this.createPostView(post).render().el);
}, this))
}
//needs to be deferred so it happens after html rendering finishes
_.defer(_.bind(this.mason, this))

View file

@ -3,6 +3,11 @@
min-width : $two-column-width + px;
max-width : $two-column-width + px;
}
.no-post-message {
text-align: center;
margin-top: 50px;
font-size: 1.2em;
}
.canvas-frame {
float : left;

View file

@ -1,173 +0,0 @@
<div class="canvas-frame">
<div class="content">
<img src="https://joindiaspora.s3.amazonaws.com/uploads/images/scaled_full_bb076dd0d45f0caa4478.gif"/>
</div>
<div class="info">
Daniel Grippi
</div>
</div>
<div class="canvas-frame width x2">
<div class="content">
<p>
Here, he discusses how globalisation has exacerbated income inequalities and the control over politics exerted by the rich, citing the Occupy movement which he describes as a 'public relations hazard not a health hazard'
</p>
<p>
Echo park wolf kale chips sunt, dolor scenester deserunt ad cray leggings 3 wolf moon thundercats direct trade. Banksy placeat odd future et, ex gastropub elit whatever. Messenger bag eu fanny pack, pitchfork locavore four loko yr marfa forage. Mcsweeney's hoodie terry richardson exercitation, consectetur commodo banh mi ullamco laboris cliche raw denim salvia selvage in nulla. Lo-fi chambray culpa, dreamcatcher fugiat squid portland nihil high life. Quis VHS blog sunt sint, salvia wes anderson fingerstache portland eiusmod ex consectetur synth enim. Tattooed aliquip proident id, lomo aliqua qui pitchfork hella cosby sweater pariatur vero. </p>
</div>
<div class="info">
Dennis Collinson
</div>
</div>
<div class="canvas-frame">
<div class="content">
<img src="https://joindiaspora.s3.amazonaws.com/uploads/images/scaled_full_7dbfea26846d99848aac.jpg"/>
</div>
<div class="info">
Sarah Mei
</div>
</div>
<div class="canvas-frame">
<div class="content">
<h1>
sometimes, i say things loud.
</h1>
</div>
<div class="info">
Sean Tilley
</div>
</div>
<div class="canvas-frame height x2">
<div class="content">
<h1>
this is a longish status but i don't have that much to say. i guess i can keep on typing or something like that or make this a run-on sentance.
</h1>
</div>
<div class="info">
Daniel Grippi
</div>
</div>
<div class="canvas-frame width x2">
<div class="content">
<p>
Echo park wolf kale chips sunt, dolor scenester deserunt ad cray leggings 3 wolf moon thundercats direct trade. Banksy placeat odd future et, ex gastropub elit whatever. Messenger bag eu fanny pack, pitchfork locavore four loko yr marfa forage. Mcsweeney's hoodie terry richardson exercitation, consectetur commodo banh mi ullamco laboris cliche raw denim salvia selvage in nulla. Lo-fi chambray culpa, dreamcatcher fugiat squid portland nihil high life. Quis VHS blog sunt sint, salvia wes anderson fingerstache portland eiusmod ex consectetur synth enim. Tattooed aliquip proident id, lomo aliqua qui pitchfork hella cosby sweater pariatur vero.
</p>
</div>
<div class="info">
Dennis Collinson
</div>
</div>
<div class="canvas-frame height width x2">
<div class="content">
<img src="http://24.media.tumblr.com/tumblr_lzwkez5ew31qzxz2so1_500.jpg"/>
</div>
<div class="info">
Sarah Mei
</div>
</div>
<div class="canvas-frame">
<div class="content">
<h1>
#weinerjuice
</h1>
</div>
<div class="info">
Sean Tilley
</div>
</div>
<div class="canvas-frame width x2">
<div class="content">
<img src="http://hipsteripsum.wpengine.netdna-cdn.com/wp-content/uploads/2011/08/cropped-asian_hipster.jpg"/>
</div>
<div class="info">
Rosanna Yau
</div>
</div>
<div class="canvas-frame height x2">
<div class="content">
<h3>
Banksy placeat odd future et, ex gastropub elit whatever. Messenger bag eu fanny pack, pitchfork locavore four loko yr marfa forage. Mcsweeney's hoodie terry richardson exercitation, consectetur commodo banh mi ullamco laboris cliche raw denim salvia selvage
Banksy placeat odd future et, ex gastropub elit whatever. Messenger bag eu fanny pack, pitchfork.
</h3>
</div>
<div class="info">
Sarah Mei
</div>
</div>
<div class="canvas-frame width height x2">
<div class="content">
<img src="http://28.media.tumblr.com/tumblr_m02dfqdQT31qfzxa7o1_500.jpg"/>
</div>
<div class="info">
Daniel Grippi
</div>
</div>
<div class="canvas-frame">
<div class="content">
<p>
Banksy placeat odd future et, ex gastropub elit whatever. Messenger bag eu fanny pack, pitchfork locavore four loko yr marfa forage. Mcsweeney's hoodie terry richardson exercitation, consectetur commodo banh mi ullamco laboris cliche raw denim salvia selvage
</p>
</div>
<div class="info">
Daniel Grippi
</div>
</div>
<div class="canvas-frame">
<div class="content">
<h1>
skribblex.
</h1>
</div>
<div class="info">
Rosanna Yau
</div>
</div>
<div class="canvas-frame height x2">
<div class="content">
<img src="http://28.media.tumblr.com/tumblr_ln5654hJrs1qd33kzo1_1280.jpg"/>
</div>
<div class="info">
Sarah Mei
</div>
</div>
<div class="canvas-frame">
<div class="content">
hey there kids!
</div>
<div class="info">
Daniel Grippi
</div>
</div>
<div class="canvas-frame width x2">
<div class="content">
<iframe width="100%" height="450" scrolling="no" frameborder="no" src="http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F1821180&show_artwork=true"></iframe>
</div>
<div class="info">
Rosanna Yau
</div>
</div>

View file

@ -119,7 +119,9 @@ class PeopleController < ApplicationController
format.all do
if params[:ex]
@page = :experimental
gon.stream = @stream.stream_posts.as_api_response(:backbone).as_json
gon.person = PersonPresenter.new(@person, current_user)
gon.stream = @stream.stream_posts.as_api_response(:backbone)
render :nothing => true, :layout => 'post'
else
respond_with @person, :locals => {:post_type => :all}

View file

@ -14,20 +14,7 @@ class ProfilesController < ApplicationController
@person = Person.find_by_guid!(params[:id])
respond_to do |format|
format.json {
public_json = @person.as_api_response(:backbone)
extra_json = {:wallpaper => @person.profile.wallpaper.url}
if(current_user && (current_user.person == @person || current_user.contacts.receiving.where(:person_id => @person.id).first))
extra_json = extra_json.merge({
:location => @person.profile.location,
:birthday => @person.profile.formatted_birthday,
:bio => @person.profile.bio
})
end
render :json => public_json.merge(extra_json)
}
format.json { render :json => PersonPresenter.new(@person, current_user) }
end
end

View file

@ -0,0 +1,34 @@
class PersonPresenter
def initialize(person, current_user = nil)
@person = person
@current_user = current_user
end
def as_json(options={})
attrs = @person.as_api_response(:backbone).merge(
{
:wallpaper => @person.profile.wallpaper.url,
:is_own_profile => is_own_profile
})
if is_own_profile || person_is_following_current_user
attrs.merge!({
:location => @person.profile.location,
:birthday => @person.profile.formatted_birthday,
:bio => @person.profile.bio
})
end
attrs
end
def is_own_profile
@current_user.try(:person) == @person
end
protected
def person_is_following_current_user
@current_user.contacts.receiving.where(:person_id => @person.id).first
end
end

View file

@ -168,7 +168,7 @@ describe PostsController do
end
end
describe "next" do
describe "#next" do
before do
sign_in alice
#lets make a class and unit test it, because this is still not working

View file

@ -1,19 +1,20 @@
describe("app.pages.Profile", function(){
beforeEach(function(){
this.guid = 'abcdefg123'
app.page = this.page = new app.pages.Profile({personId :this.guid });
this.profile = factory.profile({personId: this.guid})
app.page = this.page = new app.pages.Profile({model : this.profile });
this.stream = this.page.stream
});
it("fetches the profile of the user with the params from the router and assigns it as the model", function(){
profile = new factory.profile()
var profile = new factory.profile()
spyOn(app.models.Profile, 'findByGuid').andReturn(profile)
var page = new app.pages.Profile({personId : 'jarjabinkisthebest' })
expect(app.models.Profile.findByGuid).toHaveBeenCalledWith('jarjabinkisthebest')
expect(page.model).toBe(profile)
})
it("passes the model down to the post view", function(){
it("passes the stream down to the canvas view", function(){
expect(this.page.canvasView.model).toBeDefined()
expect(this.page.canvasView.model).toBe(this.stream)
});
@ -30,68 +31,87 @@ describe("app.pages.Profile", function(){
})
describe("rendering", function(){
beforeEach(function(){
this.post = factory.post()
this.stream.add(this.post)
this.page.toggleEdit()
expect(this.page.editMode).toBeTruthy()
this.page.render()
});
context("profile control pane", function(){
it("shows the edit and create buttons if it's your profile", function() {
spyOn(this.page, "isOwnProfile").andReturn(true)
this.page.render()
expect(this.page.$("#profile-controls .control").length).toBe(2)
})
it("shows a follow button if showFollowButton returns true", function() {
spyOn(this.page, "showFollowButton").andReturn(true)
this.page.render()
expect(this.page.$("#follow-button").length).toBe(1)
})
it("doesn't show a follow button if showFollowButton returns false", function() {
spyOn(this.page, "showFollowButton").andReturn(false)
this.page.render()
expect(this.page.$("#follow-button").length).toBe(0)
})
})
context("clicking fav", function(){
context("with no posts", function(){
beforeEach(function(){
spyOn(this.post, 'toggleFavorite')
spyOn($.fn, "isotope")
this.page.$(".content").click()
this.profile.set({"full_name" : "Alice Waters", person_id : "889"})
})
it("relayouts the page", function(){
expect($.fn.isotope).toHaveBeenCalledWith("reLayout")
it("has a message that there are no posts", function(){
this.page.render()
expect(this.page.$("#canvas").text()).toBe("Alice Waters hasn't posted anything yet.")
})
it("toggles the favorite status on the model", function(){
expect(this.post.toggleFavorite).toHaveBeenCalled()
it("tells you to post something if it's your profile", function(){
this.profile.set({is_own_profile : true})
this.page.render()
expect(this.page.$("#canvas").text()).toBe("Make something to start the magic.")
})
})
context("clicking delete", function(){
beforeEach(function () {
spyOn(window, "confirm").andReturn(true);
context("with a post", function(){
beforeEach(function(){
this.post = factory.post()
this.stream.add(this.post)
this.page.toggleEdit()
expect(this.page.editMode).toBeTruthy()
this.page.render()
});
context("profile control pane", function(){
it("shows the edit and create buttons if it's your profile", function() {
spyOn(this.page, "isOwnProfile").andReturn(true)
this.page.render()
expect(this.page.$("#profile-controls .control").length).toBe(2)
})
it("shows a follow button if showFollowButton returns true", function() {
spyOn(this.page, "showFollowButton").andReturn(true)
this.page.render()
expect(this.page.$("#follow-button").length).toBe(1)
})
it("doesn't show a follow button if showFollowButton returns false", function() {
spyOn(this.page, "showFollowButton").andReturn(false)
this.page.render()
expect(this.page.$("#follow-button").length).toBe(0)
})
})
it("kills the model", function(){
spyOn(this.post, "destroy")
this.page.$(".canvas-frame:first a.delete").click()
expect(this.post.destroy).toHaveBeenCalled()
context("clicking fav", function(){
beforeEach(function(){
spyOn(this.post, 'toggleFavorite')
spyOn($.fn, "isotope")
this.page.$(".content").click()
})
it("relayouts the page", function(){
expect($.fn.isotope).toHaveBeenCalledWith("reLayout")
})
it("toggles the favorite status on the model", function(){
expect(this.post.toggleFavorite).toHaveBeenCalled()
})
})
it("removes the frame", function(){
spyOn($.fn, "remove").andCallThrough()
expect(this.page.$(".canvas-frame").length).toBe(1)
this.page.$(".canvas-frame:first a.delete").click()
waitsFor(function(){ return $.fn.remove.wasCalled })
runs(function(){ expect(this.page.$(".canvas-frame").length).toBe(0) })
context("clicking delete", function(){
beforeEach(function () {
spyOn(window, "confirm").andReturn(true);
this.page.render()
})
it("kills the model", function(){
spyOn(this.post, "destroy")
this.page.$(".canvas-frame:first a.delete").click()
expect(this.post.destroy).toHaveBeenCalled()
})
it("removes the frame", function(){
spyOn($.fn, "remove").andCallThrough()
expect(this.page.$(".canvas-frame").length).toBe(1)
this.page.$(".canvas-frame:first a.delete").click()
waitsFor(function(){ return $.fn.remove.wasCalled })
runs(function(){ expect(this.page.$(".canvas-frame").length).toBe(0) })
})
})
})
});