backbone view for header; moved user dropdown logic in there; moved jasmine specs over; removed old widget
This commit is contained in:
parent
841cc29d25
commit
67e56dce2c
11 changed files with 175 additions and 67 deletions
|
|
@ -71,8 +71,9 @@
|
||||||
|
|
||||||
#notifications
|
#notifications
|
||||||
|
|
||||||
%header{:class=>('landing' unless current_user)}
|
- unless user_signed_in?
|
||||||
= render 'layouts/header'
|
%header{:class=>('landing')}
|
||||||
|
= render 'layouts/header'
|
||||||
|
|
||||||
= render 'templates/templates'
|
= render 'templates/templates'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
-# licensed under the Affero General Public License version 3 or later. See
|
-# licensed under the Affero General Public License version 3 or later. See
|
||||||
-# the COPYRIGHT file.
|
-# the COPYRIGHT file.
|
||||||
|
|
||||||
|
%script{:id => "header-template", :type => 'text/template'}
|
||||||
|
!= File.read("#{Rails.root}/app/views/templates/header.ujs")
|
||||||
|
|
||||||
%script{:id => "stream-element-template", :type => 'text/template'}
|
%script{:id => "stream-element-template", :type => 'text/template'}
|
||||||
!= File.read("#{Rails.root}/app/views/templates/stream_element.ujs")
|
!= File.read("#{Rails.root}/app/views/templates/stream_element.ujs")
|
||||||
|
|
||||||
|
|
@ -19,3 +22,4 @@
|
||||||
|
|
||||||
%script{:id => "activity-streams-photo-template", :type => 'text/template'}
|
%script{:id => "activity-streams-photo-template", :type => 'text/template'}
|
||||||
!= File.read("#{Rails.root}/app/views/templates/activity-streams-photo.ujs")
|
!= File.read("#{Rails.root}/app/views/templates/activity-streams-photo.ujs")
|
||||||
|
|
||||||
|
|
|
||||||
86
app/views/templates/header.ujs
Normal file
86
app/views/templates/header.ujs
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
<header>
|
||||||
|
<div class="container" style="position:relative;">
|
||||||
|
<a href="/stream"><img alt="Logo_small" class="diaspora_header_logo" height="16px" src="/images/logo_small.png?1322618579" width="161px"></a>
|
||||||
|
<div id="global_search">
|
||||||
|
<form accept-charset="UTF-8" action="/people" class="search_form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
||||||
|
<input id="q" name="q" placeholder="Find people or #tags" results="5" type="search" autocomplete="off" class="ac_input">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="nav_badges">
|
||||||
|
<div class="badge" id="home_badge">
|
||||||
|
<a href="/stream" title="Home"><img alt="Home" src="/images/icons/home_grey.png">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="badge" id="notification_badge">
|
||||||
|
<a href="/notifications" title="No new notifications">
|
||||||
|
<img alt="No new notifications" id="notification-flag" src="/images/icons/notifications_grey.png">
|
||||||
|
<div class="badge_count hidden">
|
||||||
|
0
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="badge" id="message_inbox_badge">
|
||||||
|
<a href="/conversations" title="No new messages"><img alt="No new messages" src="/images/icons/mail_grey.png">
|
||||||
|
<div class="badge_count hidden">
|
||||||
|
0
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="notification_dropdown">
|
||||||
|
<div class="header">
|
||||||
|
<div class="right">
|
||||||
|
<a href="/notifications/read_all">Mark All as Read</a>
|
||||||
|
|
|
||||||
|
<a href="/notifications" id="view_all_notifications">View all</a>
|
||||||
|
</div>
|
||||||
|
<h4>
|
||||||
|
Recent notifications
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="notifications">
|
||||||
|
<div class="ajax_loader">
|
||||||
|
<img alt="Ajax-loader" src="/images/ajax-loader.gif">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="hovercard_container">
|
||||||
|
<div id="hovercard">
|
||||||
|
<img class="avatar">
|
||||||
|
<h4>
|
||||||
|
<a class="person"></a>
|
||||||
|
</h4>
|
||||||
|
<p class="handle"></p>
|
||||||
|
<div id="hovercard_dropdown_container"></div>
|
||||||
|
<div class="hovercard_footer">
|
||||||
|
<div class="footer_container">
|
||||||
|
<div class="hashtags"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="dropdown" id="user_menu">
|
||||||
|
<li>
|
||||||
|
<div class="right">
|
||||||
|
▼
|
||||||
|
</div>
|
||||||
|
<div class="avatar">
|
||||||
|
<img alt="<%= current_user.name %>" class="avatar" data-person_id="<%= current_user.id %>" src="<%= current_user.avatar.small %>" title="Bob Grimm">
|
||||||
|
</div>
|
||||||
|
<a href="#" title="bob@localhost:3000">Bob Grimm</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="/people/<%= current_user.id %>">Profile</a></li>
|
||||||
|
<li><a href="/contacts">Contacts</a></li>
|
||||||
|
<li><a href="/user/edit">Settings</a></li>
|
||||||
|
<li><a href="/users/sign_out">Log out</a></li>
|
||||||
|
</ul>
|
||||||
|
<div id="lightbox">
|
||||||
|
<div id="lightbox-content">
|
||||||
|
<a href="#" id="lightbox-close-link">[x] close</a>
|
||||||
|
<img id="lightbox-image">
|
||||||
|
<div id="lightbox-imageset"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="lightbox-backdrop"></div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
@ -12,6 +12,12 @@ var App = {
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
App.router = new App.Router;
|
App.router = new App.Router;
|
||||||
|
|
||||||
|
if(this._user){
|
||||||
|
App.header = new App.Views.Header;
|
||||||
|
$("body").prepend(App.header.el);
|
||||||
|
App.header.render();
|
||||||
|
}
|
||||||
|
|
||||||
Backbone.history.start({pushState: true});
|
Backbone.history.start({pushState: true});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
39
public/javascripts/app/views/header_view.js
Normal file
39
public/javascripts/app/views/header_view.js
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
App.Views.Header = Backbone.View.extend({
|
||||||
|
|
||||||
|
events : {
|
||||||
|
"click ul.dropdown li:first-child" : "toggleDropdown"
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize : function(options) {
|
||||||
|
this.menuElement = this.$("ul.dropdown");
|
||||||
|
|
||||||
|
_.bindAll(this, "toggleDropdown", "hideDropdown");
|
||||||
|
this.menuElement.find("li a").slice(1).click(function(evt) { evt.stopPropagation(); });
|
||||||
|
$(document.body).click(this.hideDropdown);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
render : function(){
|
||||||
|
this.template = _.template($("#header-template").html());
|
||||||
|
$(this.el).html(this.template(App.user()));
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleDropdown : function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
|
||||||
|
this.$("ul.dropdown").toggleClass("active");
|
||||||
|
|
||||||
|
if ( $.browser.msie ) {
|
||||||
|
this.$('header').toggleClass('ie-user-menu-active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hideDropdown : function(evt) {
|
||||||
|
if(this.$("ul.dropdown").hasClass("active") && !$(evt.target).parents("#user_menu").length) {
|
||||||
|
this.$("ul.dropdown").removeClass("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
self.search = self.instantiate("Search", header.find(".search_form"));
|
self.search = self.instantiate("Search", header.find(".search_form"));
|
||||||
self.menuElement = self.instantiate("UserDropdown", header.find("#user_menu"));
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
(function() {
|
|
||||||
var UserDropdown = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.subscribe("widget/ready", function(evt, menuElement) {
|
|
||||||
$.extend(self, {
|
|
||||||
menuElement: menuElement
|
|
||||||
});
|
|
||||||
|
|
||||||
self.menuElement.click(self.toggleDropdown);
|
|
||||||
self.menuElement.find("li a").slice(1).click(function(evt) { evt.stopPropagation(); });
|
|
||||||
$(document.body).click(self.hideDropdown);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.toggleDropdown = function(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopPropagation();
|
|
||||||
|
|
||||||
self.menuElement.toggleClass("active");
|
|
||||||
|
|
||||||
if ( $.browser.msie ) {
|
|
||||||
$('header').toggleClass('ie-user-menu-active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.hideDropdown = function() {
|
|
||||||
if(self.menuElement.hasClass("active") && !$(this).parents("#user_menu").length) {
|
|
||||||
self.menuElement.removeClass("active");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Diaspora.Widgets.UserDropdown = UserDropdown;
|
|
||||||
})();
|
|
||||||
32
spec/javascripts/app/views/header_view_spec.js
Normal file
32
spec/javascripts/app/views/header_view_spec.js
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
describe("App.Views.Header", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
// should be jasmine helper
|
||||||
|
|
||||||
|
window.current_user = App.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
|
||||||
|
|
||||||
|
spec.loadFixture("aspects_index");
|
||||||
|
|
||||||
|
this.view = new App.Views.Header().render();
|
||||||
|
|
||||||
|
console.log(this.view);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#toggleDropdown", function() {
|
||||||
|
it("adds the class 'active'", function() {
|
||||||
|
expect(this.view.$(".dropdown")).not.toHaveClass("active");
|
||||||
|
this.view.toggleDropdown($.Event());
|
||||||
|
expect(this.view.$(".dropdown")).toHaveClass("active");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#hideDropdown", function() {
|
||||||
|
it("removes the class 'active' if the user clicks anywhere that isn't the menu element", function() {
|
||||||
|
this.view.toggleDropdown($.Event());
|
||||||
|
expect(this.view.$(".dropdown")).toHaveClass("active");
|
||||||
|
|
||||||
|
this.view.hideDropdown($.Event());
|
||||||
|
expect(this.view.$(".dropdown")).not.toHaveClass("active");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -20,7 +20,7 @@ describe("App.views.Stream", function(){
|
||||||
|
|
||||||
context("when rendering a Status Mesasage", function(){
|
context("when rendering a Status Mesasage", function(){
|
||||||
it("shows the status message in the content area", function(){
|
it("shows the status message in the content area", function(){
|
||||||
expect(this.statusElement.find(".post-content p").text()).toContain("jimmy's 2 whales")
|
expect(this.statusElement.find(".post-content p").text()).toContain("hella infos yo!")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
describe("Diaspora.Widgets.UserDropdown", function() {
|
|
||||||
var userDropdown;
|
|
||||||
beforeEach(function() {
|
|
||||||
spec.loadFixture("aspects_index");
|
|
||||||
userDropdown = Diaspora.BaseWidget.instantiate("UserDropdown", $("#user_menu"));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("toggleDropdown", function() {
|
|
||||||
it("adds the class 'active'", function() {
|
|
||||||
expect(userDropdown.menuElement).not.toHaveClass("active");
|
|
||||||
userDropdown.toggleDropdown($.Event());
|
|
||||||
expect(userDropdown.menuElement).toHaveClass("active");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("hideDropdown", function() {
|
|
||||||
it("removes the class 'active' if the user clicks anywhere that isn't the menu element", function() {
|
|
||||||
userDropdown.toggleDropdown($.Event());
|
|
||||||
expect(userDropdown.menuElement).toHaveClass("active");
|
|
||||||
|
|
||||||
userDropdown.hideDropdown();
|
|
||||||
expect(userDropdown.menuElement).not.toHaveClass("active");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Loading…
Reference in a new issue