Merge pull request #3802 from Raven24/hovercards
Bring back the hovercards... backbone style
This commit is contained in:
commit
679d119d4d
13 changed files with 243 additions and 159 deletions
|
|
@ -20,6 +20,7 @@
|
||||||
* Add progress percentage to upload images. [#3740](https://github.com/diaspora/diaspora/pull/3740)
|
* Add progress percentage to upload images. [#3740](https://github.com/diaspora/diaspora/pull/3740)
|
||||||
* Mark all unread post-related notifications as read, if one of this gets opened. [#3787](https://github.com/diaspora/diaspora/pull/3787)
|
* Mark all unread post-related notifications as read, if one of this gets opened. [#3787](https://github.com/diaspora/diaspora/pull/3787)
|
||||||
* Add flash-notice when sending messages to non-contacts. [#3723](https://github.com/diaspora/diaspora/pull/3723)
|
* Add flash-notice when sending messages to non-contacts. [#3723](https://github.com/diaspora/diaspora/pull/3723)
|
||||||
|
* Re-add hovercards [#3802](https://github.com/diaspora/diaspora/pull/3802)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ var app = {
|
||||||
app.currentUser = app.user(window.current_user_attributes) || new app.models.User()
|
app.currentUser = app.user(window.current_user_attributes) || new app.models.User()
|
||||||
|
|
||||||
if(app.currentUser.authenticated()){
|
if(app.currentUser.authenticated()){
|
||||||
app.header = new app.views.Header;
|
app.header = new app.views.Header();
|
||||||
$("header").prepend(app.header.el);
|
$("header").prepend(app.header.el);
|
||||||
app.header.render();
|
app.header.render();
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +52,9 @@ var app = {
|
||||||
|
|
||||||
$(".stream_title").text(link.text())
|
$(".stream_title").text(link.text())
|
||||||
app.router.navigate(link.attr("href").substring(1) ,true)
|
app.router.navigate(link.attr("href").substring(1) ,true)
|
||||||
})
|
});
|
||||||
|
|
||||||
|
app.hovercard = new app.views.Hovercard();
|
||||||
},
|
},
|
||||||
|
|
||||||
hasPreload : function(prop) {
|
hasPreload : function(prop) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
Handlebars.registerHelper('t', function(scope, values) {
|
Handlebars.registerHelper('t', function(scope, values) {
|
||||||
return Diaspora.I18n.t(scope, values.hash)
|
return Diaspora.I18n.t(scope, values.hash)
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('imageUrl', function(path){
|
Handlebars.registerHelper('imageUrl', function(path){
|
||||||
return app.baseImageUrl() + path;
|
return app.baseImageUrl() + path;
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('linkToPerson', function(context, block) {
|
Handlebars.registerHelper('linkToPerson', function(context, block) {
|
||||||
var html = "<a href=\"/people/" + context.guid + "\" class=\"author-name\">";
|
var html = "<a href=\"/people/" + context.guid + "\" class=\"author-name\">";
|
||||||
|
|
@ -12,15 +12,29 @@ Handlebars.registerHelper('linkToPerson', function(context, block) {
|
||||||
html+= "</a>";
|
html+= "</a>";
|
||||||
|
|
||||||
return html
|
return html
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// allow hovercards for users that are not the current user.
|
||||||
|
// returns the html class name used to trigger hovercards.
|
||||||
|
Handlebars.registerHelper('hovercardable', function(person) {
|
||||||
|
if( app.currentUser.get('guid') != person.guid ) {
|
||||||
|
return 'hovercardable';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('personImage', function(person, size, imageClass) {
|
Handlebars.registerHelper('personImage', function(person, size, imageClass) {
|
||||||
/* we return here if person.avatar is blank, because this happens when a
|
/* we return here if person.avatar is blank, because this happens when a
|
||||||
* user is unauthenticated. we don't know why this happens... */
|
* user is unauthenticated. we don't know why this happens... */
|
||||||
if(typeof(person.avatar) == "undefined") { return }
|
if( _.isUndefined(person.avatar) ) { return }
|
||||||
|
|
||||||
size = (typeof(size) != "string" ? "small" : size);
|
size = ( !_.isString(size) ) ? "small" : size;
|
||||||
imageClass = (typeof(imageClass) != "string" ? size : imageClass);
|
imageClass = ( !_.isString(imageClass) ) ? size : imageClass;
|
||||||
|
|
||||||
return "<img src=\"" + person.avatar[size] +"\" class=\"avatar " + imageClass + "\" title=\"" + _.escape(person.name) +"\" />";
|
return _.template('<img src="<%= src %>" class="avatar <%= img_class %>" title="<%= title %>" />', {
|
||||||
})
|
'src': person.avatar[size],
|
||||||
|
'img_class': imageClass,
|
||||||
|
'title': _.escape(person.name)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
115
app/assets/javascripts/app/views/hovercard_view.js
Normal file
115
app/assets/javascripts/app/views/hovercard_view.js
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
|
||||||
|
app.views.Hovercard = Backbone.View.extend({
|
||||||
|
el: '#hovercard_container',
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
$('.hovercardable')
|
||||||
|
.live('mouseenter', _.bind(this._mouseenterHandler, this))
|
||||||
|
.live('mouseleave', _.bind(this._mouseleaveHandler, this));
|
||||||
|
|
||||||
|
this.show_me = false;
|
||||||
|
|
||||||
|
this.avatar = this.$('.avatar');
|
||||||
|
this.dropdown = this.$('.dropdown_list');
|
||||||
|
this.dropdown_container = this.$('#hovercard_dropdown_container');
|
||||||
|
this.hashtags = this.$('.hashtags');
|
||||||
|
this.person_link = this.$('a.person');
|
||||||
|
this.person_handle = this.$('p.handle');
|
||||||
|
},
|
||||||
|
|
||||||
|
href: function() {
|
||||||
|
return this.$el.parent().attr('href');
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseenterHandler: function(event) {
|
||||||
|
var el = $(event.target);
|
||||||
|
if( !el.is('a') ) {
|
||||||
|
el = el.parents('a');
|
||||||
|
}
|
||||||
|
|
||||||
|
if( el.attr('href').indexOf('/people') == -1 ) {
|
||||||
|
// can't fetch data from that URL, aborting
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.show_me = true;
|
||||||
|
this.showHovercardOn(el);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseleaveHandler: function(event) {
|
||||||
|
this.show_me = false;
|
||||||
|
if( this.$el.is(':visible') ) {
|
||||||
|
this.$el.fadeOut('fast');
|
||||||
|
} else {
|
||||||
|
this.$el.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dropdown_container.empty();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
showHovercardOn: _.debounce(function(element) {
|
||||||
|
var el = $(element);
|
||||||
|
var hc = this.$el;
|
||||||
|
|
||||||
|
if( !this.show_me ) {
|
||||||
|
// mouse has left element
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hc.hide();
|
||||||
|
hc.prependTo(el);
|
||||||
|
this._positionHovercard();
|
||||||
|
this._populateHovercard();
|
||||||
|
}, 500, true),
|
||||||
|
|
||||||
|
_populateHovercard: function() {
|
||||||
|
var href = this.href();
|
||||||
|
href += "/hovercard.json";
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
$.get(href, function(person){
|
||||||
|
if( !person || person.length == 0 ) {
|
||||||
|
throw new Error("received data is not a person object");
|
||||||
|
}
|
||||||
|
|
||||||
|
self._populateHovercardWith(person);
|
||||||
|
self.$el.fadeIn('fast');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_populateHovercardWith: function(person) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.avatar.attr('src', person.avatar);
|
||||||
|
this.person_link.attr('href', person.url);
|
||||||
|
this.person_link.text(person.name);
|
||||||
|
this.person_handle.text(person.handle);
|
||||||
|
this.dropdown.attr('data-person-id', person.id);
|
||||||
|
|
||||||
|
// set hashtags
|
||||||
|
this.hashtags.empty();
|
||||||
|
this.hashtags.html( $(_.map(person.tags, function(tag){
|
||||||
|
return $('<a/>',{href: "/tags/"+tag.substring(1)}).text(tag)[0] ;
|
||||||
|
})) );
|
||||||
|
|
||||||
|
// set aspect dropdown
|
||||||
|
var href = this.href();
|
||||||
|
href += "/aspect_membership_button"
|
||||||
|
$.get(href, function(response) {
|
||||||
|
self.dropdown_container.html(response);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionHovercard: function() {
|
||||||
|
var p = this.$el.parent();
|
||||||
|
var p_pos = p.position();
|
||||||
|
var p_height = p.height();
|
||||||
|
|
||||||
|
this.$el.css({
|
||||||
|
top: p_pos.top + p_height - 25,
|
||||||
|
left: p_pos.left
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -64,7 +64,6 @@
|
||||||
events: function() { return Diaspora.page.eventsContainer.data("events"); },
|
events: function() { return Diaspora.page.eventsContainer.data("events"); },
|
||||||
flashMessages: this.instantiate("FlashMessages"),
|
flashMessages: this.instantiate("FlashMessages"),
|
||||||
header: this.instantiate("Header", body.find("header")),
|
header: this.instantiate("Header", body.find("header")),
|
||||||
hoverCard: this.instantiate("HoverCard", body.find("#hovercard")),
|
|
||||||
timeAgo: this.instantiate("TimeAgo")
|
timeAgo: this.instantiate("TimeAgo")
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
(function() {
|
|
||||||
var HoverCard = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.jXHRs = [];
|
|
||||||
|
|
||||||
self.subscribe("widget/ready", function(evt, hoverCard) {
|
|
||||||
self.personCache = new self.Cache();
|
|
||||||
self.dropdownCache = new self.Cache();
|
|
||||||
|
|
||||||
self.hoverCard = {
|
|
||||||
tip: $("#hovercard_container"),
|
|
||||||
dropdownContainer: $("#hovercard_dropdown_container"),
|
|
||||||
offset: {
|
|
||||||
left: -10,
|
|
||||||
top: 13
|
|
||||||
},
|
|
||||||
personLink: hoverCard.find("a.person"),
|
|
||||||
personHandle: hoverCard.find("p.handle"),
|
|
||||||
avatar: hoverCard.find(".avatar"),
|
|
||||||
dropdown: hoverCard.find(".dropdown_list"),
|
|
||||||
hashtags: hoverCard.find(".hashtags")
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document.body).delegate("a.hovercardable:not(.self)", "hover", self.handleHoverEvent);
|
|
||||||
self.hoverCard.tip.hover(self.hoverCardHover, self.clearTimeout);
|
|
||||||
|
|
||||||
self.subscribe("aspectDropdown/updated aspectDropdown/blurred", function(evt, personId, dropdownHtml) {
|
|
||||||
self.dropdownCache.cache["/people/" + personId + "/aspect_membership_button"] = $(dropdownHtml).removeClass("active").get(0).outerHTML;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.handleHoverEvent = function(evt) {
|
|
||||||
self.target = $(evt.target);
|
|
||||||
|
|
||||||
if(evt.type === "mouseenter") {
|
|
||||||
self.startHover();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.clearTimeout(evt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.startHover = function(evt) {
|
|
||||||
if(!self.hoverCardTimeout) {
|
|
||||||
self.clearTimeout(false);
|
|
||||||
}
|
|
||||||
self.timeout = setTimeout(self.showHoverCard, 600);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.showHoverCard = function() {
|
|
||||||
self.hoverCard.tip.hide();
|
|
||||||
self.hoverCard.tip.prependTo(self.target.parent());
|
|
||||||
|
|
||||||
self.personCache.get(self.target.attr("data-hovercard") + ".json?includes=tags", function(person) {
|
|
||||||
self.populateHovercard(person);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.populateHovercard = function(person) {
|
|
||||||
var position = self.target.position();
|
|
||||||
self.hoverCard.tip.css({
|
|
||||||
left: position.left + self.hoverCard.offset.left,
|
|
||||||
top: position.top + self.hoverCard.offset.top
|
|
||||||
});
|
|
||||||
|
|
||||||
self.hoverCard.avatar.attr("src", person.avatar);
|
|
||||||
self.hoverCard.personLink.attr("href", person.url);
|
|
||||||
self.hoverCard.personLink.text(person.name);
|
|
||||||
self.hoverCard.personHandle.text(person.handle);
|
|
||||||
self.hoverCard.dropdown.attr("data-person-id", person.id);
|
|
||||||
|
|
||||||
self.hoverCard.hashtags.html("");
|
|
||||||
$.each(person.tags, function(index, hashtag) {
|
|
||||||
self.hoverCard.hashtags.append(
|
|
||||||
$("<a/>", {
|
|
||||||
href: "/tags/" + hashtag.substring(1)
|
|
||||||
}).text(hashtag)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.dropdownCache.get(self.target.attr("data-hovercard") + "/aspect_membership_button", function(dropdown) {
|
|
||||||
self.hoverCard.dropdownContainer.html(dropdown);
|
|
||||||
self.hoverCard.tip.fadeIn(140);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clearTimeout = function(delayed) {
|
|
||||||
self.personCache.clearjXHRs();
|
|
||||||
self.dropdownCache.clearjXHRs();
|
|
||||||
|
|
||||||
function callback() {
|
|
||||||
self.timeout = clearTimeout(self.timeout);
|
|
||||||
self.hoverCard.tip.hide();
|
|
||||||
self.hoverCard.dropdownContainer.html("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if((typeof delayed === "boolean" && delayed) || (typeof delayed === "object" && delayed.type === "mouseleave")) {
|
|
||||||
self.hoverCardTimeout = setTimeout(callback, 20);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.hoverCardHover = function() {
|
|
||||||
self.hoverCardTimeout = clearTimeout(self.hoverCardTimeout);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Cache = function() {
|
|
||||||
var self = this;
|
|
||||||
this.cache = {};
|
|
||||||
this.jXHRs = [];
|
|
||||||
|
|
||||||
this.get = function(key, callback) {
|
|
||||||
if(typeof self.cache[key] === "undefined") {
|
|
||||||
self.jXHRs.push($.get(key, function(response) {
|
|
||||||
self.cache[key] = response;
|
|
||||||
callback(response);
|
|
||||||
self.jXHRs.shift();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback(self.cache[key]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clearjXHRs = function() {
|
|
||||||
$.each(self.jXHRs, function(index, jXHR) {
|
|
||||||
jXHR.abort();
|
|
||||||
});
|
|
||||||
self.jXHRs = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Diaspora.Widgets.HoverCard = HoverCard;
|
|
||||||
})();
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
|
||||||
background-color: $background;
|
background-color: $background;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
border: 1px solid #999999;
|
border: 1px solid #999999;
|
||||||
|
|
@ -32,13 +32,17 @@
|
||||||
& > h4, & > div, & > p {
|
& > h4, & > div, & > p {
|
||||||
margin-left: $image_width;
|
margin-left: $image_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > h4, & > div, & > p, .hashtags {
|
& > h4, & > div, & > p, .hashtags {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hovercard_dropdown_container {
|
||||||
|
overflow: visible !important; /* otherwise the aspect dropdown is cropped */
|
||||||
|
}
|
||||||
|
|
||||||
padding: 5px {
|
padding: 5px {
|
||||||
bottom: 25px;
|
bottom: 25px;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#with author}}
|
{{#with author}}
|
||||||
<a href="/people/{{guid}}" class="img">
|
<a href="/people/{{guid}}" class="img {{{hovercardable this}}}">
|
||||||
{{{personImage this}}}
|
{{{personImage this}}}
|
||||||
</a>
|
</a>
|
||||||
{{/with}}
|
{{/with}}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,13 @@ class PeopleController < ApplicationController
|
||||||
:format => :html, :layout => false, :status => 404
|
:format => :html, :layout => false, :status => 404
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rescue_from Diaspora::AccountClosed do
|
||||||
|
respond_to do |format|
|
||||||
|
format.any { redirect_to :back, :notice => t("people.show.closed_account") }
|
||||||
|
format.json { render :nothing => true, :status => 410 } # 410 GONE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
helper_method :search_query
|
helper_method :search_query
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
@ -36,7 +43,7 @@ class PeopleController < ApplicationController
|
||||||
if diaspora_id?(search_query)
|
if diaspora_id?(search_query)
|
||||||
@people = Person.where(:diaspora_handle => search_query.downcase)
|
@people = Person.where(:diaspora_handle => search_query.downcase)
|
||||||
if @people.empty?
|
if @people.empty?
|
||||||
Webfinger.in_background(search_query)
|
Webfinger.in_background(search_query)
|
||||||
@background_query = search_query.downcase
|
@background_query = search_query.downcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -66,11 +73,12 @@ class PeopleController < ApplicationController
|
||||||
respond_with @people
|
respond_with @people
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# renders the persons user profile page
|
||||||
def show
|
def show
|
||||||
@person = Person.find_from_guid_or_username(params)
|
@person = Person.find_from_guid_or_username(params)
|
||||||
|
|
||||||
authenticate_user! if remote_profile_with_no_user_session?
|
authenticate_user! if remote_profile_with_no_user_session?
|
||||||
return redirect_to :back, :notice => t("people.show.closed_account") if @person.closed_account?
|
raise Diaspora::AccountClosed if @person.closed_account?
|
||||||
|
|
||||||
@post_type = :all
|
@post_type = :all
|
||||||
@aspect = :profile
|
@aspect = :profile
|
||||||
|
|
@ -108,6 +116,23 @@ class PeopleController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# hovercards fetch some the persons public profile data via json and display
|
||||||
|
# it next to the avatar image in a nice box
|
||||||
|
def hovercard
|
||||||
|
@person = Person.find_from_guid_or_username({:id => params[:person_id]})
|
||||||
|
raise Diaspora::AccountClosed if @person.closed_account?
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.all do
|
||||||
|
redirect_to :action => "show", :id => params[:person_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
format.json do
|
||||||
|
render :json => HovercardPresenter.new(@person)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def last_post
|
def last_post
|
||||||
@person = Person.find_from_guid_or_username(params)
|
@person = Person.find_from_guid_or_username(params)
|
||||||
last_post = Post.visible_from_author(@person, current_user).order('posts.created_at DESC').first
|
last_post = Post.visible_from_author(@person, current_user).order('posts.created_at DESC').first
|
||||||
|
|
@ -148,8 +173,6 @@ class PeopleController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def redirect_if_tag_search
|
def redirect_if_tag_search
|
||||||
if search_query.starts_with?('#')
|
if search_query.starts_with?('#')
|
||||||
if search_query.length > 1
|
if search_query.length > 1
|
||||||
|
|
@ -162,6 +185,8 @@ class PeopleController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
def hashes_for_people(people, aspects)
|
def hashes_for_people(people, aspects)
|
||||||
ids = people.map{|p| p.id}
|
ids = people.map{|p| p.id}
|
||||||
contacts = {}
|
contacts = {}
|
||||||
|
|
|
||||||
39
app/presenters/hovercard_presenter.rb
Normal file
39
app/presenters/hovercard_presenter.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
class HovercardPresenter
|
||||||
|
|
||||||
|
attr_accessor :person
|
||||||
|
|
||||||
|
# initialize the presenter with the given Person object
|
||||||
|
def initialize(person)
|
||||||
|
raise ArgumentError, "the given object is not a Person" unless person.class == Person
|
||||||
|
|
||||||
|
self.person = person
|
||||||
|
end
|
||||||
|
|
||||||
|
# returns the json representation of the Person object for use with the
|
||||||
|
# hovercard UI
|
||||||
|
def to_json(options={})
|
||||||
|
{ :id => person.id,
|
||||||
|
:avatar => avatar('small'),
|
||||||
|
:url => profile_url,
|
||||||
|
:name => person.name,
|
||||||
|
:handle => person.diaspora_handle,
|
||||||
|
:tags => person.tags.map { |t| "#"+t.name }
|
||||||
|
}.to_json(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
# get the image url of the profile avatar for the given size
|
||||||
|
# possible sizes: 'small', 'medium', 'large'
|
||||||
|
def avatar(size="small")
|
||||||
|
if !["small", "medium", "large"].include?(size)
|
||||||
|
raise ArgumentError, "the given parameter is not a valid size"
|
||||||
|
end
|
||||||
|
|
||||||
|
person.image_url("thumb_#{size}".to_sym)
|
||||||
|
end
|
||||||
|
|
||||||
|
# return the (relative) url to the user profile page.
|
||||||
|
# uses the 'person_path' url helper from the rails routes
|
||||||
|
def profile_url
|
||||||
|
Rails.application.routes.url_helpers.person_path(person)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -9,7 +9,7 @@ Diaspora::Application.routes.draw do
|
||||||
|
|
||||||
|
|
||||||
get "/atom.xml" => redirect('http://blog.diasporafoundation.org/feed/atom') #too many stupid redirects :()
|
get "/atom.xml" => redirect('http://blog.diasporafoundation.org/feed/atom') #too many stupid redirects :()
|
||||||
|
|
||||||
get 'oembed' => 'posts#oembed', :as => 'oembed'
|
get 'oembed' => 'posts#oembed', :as => 'oembed'
|
||||||
# Posting and Reading
|
# Posting and Reading
|
||||||
resources :reshares
|
resources :reshares
|
||||||
|
|
@ -48,7 +48,7 @@ Diaspora::Application.routes.draw do
|
||||||
get "liked" => "streams#liked", :as => "liked_stream"
|
get "liked" => "streams#liked", :as => "liked_stream"
|
||||||
get "commented" => "streams#commented", :as => "commented_stream"
|
get "commented" => "streams#commented", :as => "commented_stream"
|
||||||
get "aspects" => "streams#aspects", :as => "aspects_stream"
|
get "aspects" => "streams#aspects", :as => "aspects_stream"
|
||||||
|
|
||||||
resources :aspects do
|
resources :aspects do
|
||||||
put :toggle_contact_visibility
|
put :toggle_contact_visibility
|
||||||
end
|
end
|
||||||
|
|
@ -114,7 +114,7 @@ Diaspora::Application.routes.draw do
|
||||||
get 'invitations/email' => 'invitations#email', :as => 'invite_email'
|
get 'invitations/email' => 'invitations#email', :as => 'invite_email'
|
||||||
get 'users/invitations' => 'invitations#new', :as => 'new_user_invitation'
|
get 'users/invitations' => 'invitations#new', :as => 'new_user_invitation'
|
||||||
post 'users/invitations' => 'invitations#create', :as => 'new_user_invitation'
|
post 'users/invitations' => 'invitations#create', :as => 'new_user_invitation'
|
||||||
|
|
||||||
get 'login' => redirect('/users/sign_in')
|
get 'login' => redirect('/users/sign_in')
|
||||||
|
|
||||||
scope 'admins', :controller => :admins do
|
scope 'admins', :controller => :admins do
|
||||||
|
|
@ -145,6 +145,7 @@ Diaspora::Application.routes.draw do
|
||||||
resources :photos
|
resources :photos
|
||||||
get :contacts
|
get :contacts
|
||||||
get "aspect_membership_button" => :aspect_membership_dropdown, :as => "aspect_membership_button"
|
get "aspect_membership_button" => :aspect_membership_dropdown, :as => "aspect_membership_button"
|
||||||
|
get :hovercard
|
||||||
|
|
||||||
member do
|
member do
|
||||||
get :last_post
|
get :last_post
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,12 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
module Diaspora
|
module Diaspora
|
||||||
|
# the post in question is not public, and that is somehow a problem
|
||||||
class NonPublic < StandardError
|
class NonPublic < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# the account was closed and that should not be the case if we want
|
||||||
|
# to continue
|
||||||
|
class AccountClosed < StandardError
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,23 @@ describe PeopleController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#hovercard' do
|
||||||
|
before do
|
||||||
|
@hover_test = FactoryGirl.create(:person)
|
||||||
|
@hover_test.profile.tag_string = '#test #tags'
|
||||||
|
@hover_test.profile.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects html requests' do
|
||||||
|
get :hovercard, :person_id => @hover_test.guid
|
||||||
|
response.should redirect_to person_path(:id => @hover_test.guid)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns json with profile stuff' do
|
||||||
|
get :hovercard, :person_id => @hover_test.guid, :format => 'json'
|
||||||
|
JSON.parse( response.body )['handle'].should == @hover_test.diaspora_handle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#refresh_search ' do
|
describe '#refresh_search ' do
|
||||||
before(:each)do
|
before(:each)do
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue