Skip to content
Extraits de code Groupes Projets
Valider 2572fb77 rédigé par Florian Staudacher's avatar Florian Staudacher
Parcourir les fichiers

* refactored text direction detector into helper (also for handlebars)

* added handlebars helper for markdown formatting
* finished port of profile sidebar view to handlebars template
* people_controller refactoring
parent 9a16560d
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 232 ajouts et 70 suppressions
(function() {
app.helpers.txtDirection = {
setCssFor: function(str, on_element) {
if( this.isRTL(str) ) {
$(on_element).css('direction', 'rtl');
} else {
$(on_element).css('direction', 'ltr');
}
},
classFor: function(str) {
if( this.isRTL(str) ) return 'rtl';
return 'ltr';
},
isRTL: function(str) {
if(typeof str !== "string" || str.length < 1) {
return false;
}
var charCode = str.charCodeAt(0);
if(charCode >= 1536 && charCode <= 1791) // Sarabic, Persian, ...
return true;
else if(charCode >= 65136 && charCode <= 65279) // Arabic present 1
return true;
else if(charCode >= 64336 && charCode <= 65023) // Arabic present 2
return true;
else if(charCode>=1424 && charCode<=1535) // Hebrew
return true;
else if(charCode>=64256 && charCode<=64335) // Hebrew present
return true;
else if(charCode>=1792 && charCode<=1871) // Syriac
return true;
else if(charCode>=1920 && charCode<=1983) // Thaana
return true;
else if(charCode>=1984 && charCode<=2047) // NKo
return true;
else if(charCode>=11568 && charCode<=11647) // Tifinagh
return true;
return false;
}
};
})();
......@@ -2,6 +2,10 @@ Handlebars.registerHelper('t', function(scope, values) {
return Diaspora.I18n.t(scope, values.hash)
});
Handlebars.registerHelper('txtDirClass', function(str) {
return app.helpers.txtDirection.classFor(str);
});
Handlebars.registerHelper('imageUrl', function(path){
return ImagePaths.get(path);
});
......@@ -72,3 +76,7 @@ Handlebars.registerHelper('personImage', function(person, size, imageClass) {
Handlebars.registerHelper('localTime', function(timestamp) {
return new Date(timestamp).toLocaleString();
});
Handlebars.registerHelper('fmtText', function(text) {
return new Handlebars.SafeString(app.helpers.textFormatter(text, null));
});
......@@ -7,7 +7,7 @@ $(function() {
(function(){
//make it so I take text and mentions rather than the modelapp.helpers.textFormatter(
var textFormatter = function textFormatter(text, model) {
var mentions = model.get("mentioned_people");
var mentions = model ? model.get("mentioned_people") : [];
return textFormatter.mentionify(
textFormatter.hashtagify(
......
......@@ -6,7 +6,7 @@ app.pages.Profile = app.views.Base.extend({
},
subviews: {
'#profile .badge': 'sidebarView',
'#profile': 'sidebarView',
'.profile_header': 'headerView'
},
......@@ -15,6 +15,10 @@ app.pages.Profile = app.views.Base.extend({
initialize: function(opts) {
if( app.hasPreload('person') )
this.model = new app.models.Person(app.parsePreload('person'));
if( app.hasPreload('photos') )
this.photos = app.parsePreload('photos'); // we don't interact with it, so no model
if( app.hasPreload('contacts') )
this.contacts = app.parsePreload('contacts'); // we don't interact with it, so no model
this.model.on('change', this.render, this);
......@@ -26,7 +30,11 @@ app.pages.Profile = app.views.Base.extend({
},
sidebarView: function() {
return new app.views.ProfileSidebar({model: this.model});
return new app.views.ProfileSidebar({
model: this.model,
photos: this.photos,
contacts: this.contacts
});
},
headerView: function() {
......
......@@ -2,13 +2,23 @@
app.views.ProfileSidebar = app.views.Base.extend({
templateName: 'profile_sidebar',
initialize: function(opts) {
this.photos = _.has(opts, 'photos') ? opts.photos : null;
this.contacts = _.has(opts, 'contacts') ? opts.contacts : null;
},
presenter: function() {
return _.extend({}, this.defaultPresenter(), {
do_profile_btns: this._shouldDoProfileBtns(),
do_profile_info: this._shouldDoProfileInfo(),
do_photos: this._shouldDoPhotos(),
do_contacts: this._shouldDoContacts(),
is_sharing: this.model.isSharing(),
is_receiving: this.model.isReceiving(),
is_mutual: this.model.isMutual(),
is_not_blocked: !this.model.isBlocked()
is_not_blocked: !this.model.isBlocked(),
photos: this.photos,
contacts: this.contacts
});
},
......@@ -16,6 +26,18 @@ app.views.ProfileSidebar = app.views.Base.extend({
return (app.currentUser.authenticated() && !this.model.get('is_own_profile'));
},
_shouldDoProfileInfo: function() {
return (this.model.isSharing() || this.model.get('is_own_profile'));
},
_shouldDoPhotos: function() {
return (this.photos && this.photos.items.length > 0);
},
_shouldDoContacts: function() {
return (this.contacts && this.contacts.items.length > 0);
},
postRenderTemplate: function() {
// UGLY (re-)attach the facebox
this.$('a[rel*=facebox]').facebox();
......
......@@ -11,47 +11,13 @@
this.subscribe("widget/ready", function() {
self.updateBinds();
self.globalSubscribe("stream/scrolled", function() {
self.updateBinds();
});
});
this.isRTL = function(str) {
if(typeof str !== "string" || str.length < 1) {
return false;
}
var charCode = str.charCodeAt(0);
if(charCode >= 1536 && charCode <= 1791) // Sarabic, Persian, ...
return true;
else if(charCode >= 65136 && charCode <= 65279) // Arabic present 1
return true;
else if(charCode >= 64336 && charCode <= 65023) // Arabic present 2
return true;
else if(charCode>=1424 && charCode<=1535) // Hebrew
return true;
else if(charCode>=64256 && charCode<=64335) // Hebrew present
return true;
else if(charCode>=1792 && charCode<=1871) // Syriac
return true;
else if(charCode>=1920 && charCode<=1983) // Thaana
return true;
else if(charCode>=1984 && charCode<=2047) // NKo
return true;
else if(charCode>=11568 && charCode<=11647) // Tifinagh
return true;
return false;
};
this.isRTL = app.helpers.txtDirection;
this.updateBinds = function() {
$.each(self.binds, function(index, bind) {
......@@ -71,14 +37,9 @@
this.updateDirection = function() {
var textArea = $(this),
cleaned = textArea.val().replace(self.cleaner, "").replace(/^[ ]+/, "");
cleaned = textArea.val().replace(self.cleaner, "").replace(/^[ ]+/, "");
if(self.isRTL(cleaned)) {
textArea.css("direction", "rtl");
}
else {
textArea.css("direction", "ltr");
}
app.helpers.txtDirection.setCssFor(cleaned, textArea);
};
};
......
<div class="profile_photo">
<div id="profile_photo" class="profile_photo">
{{#linkToPerson this}}
{{{personImage this "l"}}}
{{/linkToPerson}}
......@@ -37,3 +37,66 @@
{{/if}}
</div>
{{/if}}
{{#if do_profile_info}}
<ul id="profile_information">
{{#with profile}}
{{#if bio}}
<li>
<h4>{{t 'profile.bio'}}</h4>
<div class="{{txtDirClass bio}}">{{fmtText bio}}</div>
</li>
{{/if}}
{{#if location}}
<li>
<h4>{{t 'profile.location'}}</h4>
<div class="{{txtDirClass location}}">{{fmtText location}}</div>
</li>
{{/if}}
{{#if gender}}
<li>
<h4>{{t 'profile.gender'}}</h4>
{{gender}}
</li>
{{/if}}
{{#if birthday}}
<li>
<h4>{{t 'profile.born'}}</h4>
{{birthday}}
</li>
{{/if}}
{{/with}}
{{#if do_photos}}
<li class="image_list">
<h4>
{{t 'profile.photos'}}
<div class="item_count">{{photos.count}}</div>
</h4>
<div class="section photo_pictures">
{{#each photos.items}}
<img src="{{sizes.s}}" alt="{{guid}}" />
{{/each}}
</div>
<p class="see_all">
<a href="{{urlTo 'person_photos' guid}}">{{t 'header.view_all'}}</a>
</p>
</li>
{{/if}}
{{#if do_contacts}}
<li class="image_list">
<h4>
{{t 'profile.contacts'}}
<div class="item_count">{{contacts.count}}</div>
</h4>
<div class="section contact_pictures">
{{#each contacts.items}}
{{#linkToPerson this}}{{{personImage this "s"}}}{{/linkToPerson}}
{{/each}}
</div>
<p class="see_all">
<a href="{{urlTo 'person_contacts' guid}}">{{t 'header.view_all'}}</a>
</p>
</li>
{{/if}}
</ul>
{{/if}}
......@@ -3,7 +3,8 @@
# the COPYRIGHT file.
class PeopleController < ApplicationController
before_action :authenticate_user!, :except => [:show, :last_post]
before_action :authenticate_user!, except: [:show, :last_post]
before_action :find_person, only: [:show, :stream]
use_bootstrap_for :index
......@@ -74,12 +75,6 @@ class PeopleController < ApplicationController
# renders the persons user profile page
def show
@person = Person.find_from_guid_or_username(params)
# view this profile on the home pod, if you don't want to sign in...
authenticate_user! if remote_profile_with_no_user_session?
raise Diaspora::AccountClosed if @person.closed_account?
mark_corresponding_notifications_read if user_signed_in?
@aspect = :profile # let aspect dropdown create new aspects
......@@ -89,19 +84,26 @@ class PeopleController < ApplicationController
respond_to do |format|
format.all do
@profile = @person.profile
@photos = photos_from(@person)
if current_user
@block = current_user.blocks.where(:person_id => @person.id).first
@contact = current_user.contact_for(@person)
if @contact && !params[:only_posts]
@contacts_of_contact_count = @contact.contacts.count(:all)
@contacts_of_contact = @contact.contacts.limit(8)
@contacts_of_contact_count = contact_contacts.count(:all)
@contacts_of_contact = contact_contacts.limit(8)
else
@contact ||= Contact.new
end
end
gon.preloads[:person] = @person_json
gon.preloads[:photos] = {
count: photos_from(@person).count(:all),
items: PhotoPresenter.as_collection(photos_from(@person).limit(8), :base_hash)
}
gon.preloads[:contacts] = {
count: contact_contacts.count(:all),
items: PersonPresenter.as_collection(contact_contacts.limit(8), :full_hash_with_avatar, current_user)
}
respond_with @person, :locals => {:post_type => :all}
end
......@@ -110,11 +112,6 @@ class PeopleController < ApplicationController
end
def stream
@person = Person.find_from_guid_or_username(params)
authenticate_user! if remote_profile_with_no_user_session?
raise Diaspora::AccountClosed if @person.closed_account?
respond_to do |format|
format.all { redirect_to person_path(@person) }
format.json do
......@@ -161,8 +158,8 @@ class PeopleController < ApplicationController
if @person
@contact = current_user.contact_for(@person)
@aspect = :profile
@contacts_of_contact = @contact.contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15))
@contacts_of_contact_count = @contact.contacts.count(:all)
@contacts_of_contact = contact_contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15))
@contacts_of_contact_count = contact_contacts.count(:all)
@hashes = hashes_for_people @contacts_of_contact, @aspects
else
flash[:error] = I18n.t 'people.show.does_not_exist'
......@@ -187,6 +184,14 @@ class PeopleController < ApplicationController
private
def find_person
@person = Person.find_from_guid_or_username(params)
# view this profile on the home pod, if you don't want to sign in...
authenticate_user! if remote_profile_with_no_user_session?
raise Diaspora::AccountClosed if @person.closed_account?
end
def hashes_for_people(people, aspects)
ids = people.map{|p| p.id}
contacts = {}
......@@ -214,13 +219,23 @@ class PeopleController < ApplicationController
end
def photos_from(person)
photos = if user_signed_in?
@photos ||= if user_signed_in?
current_user.photos_from(person)
else
Photo.where(author_id: person.id, public: true)
end
end.order('created_at desc')
end
photos.order('created_at desc')
# given a `@person` find the contacts that person has in that aspect(?)
# or use your own contacts if it's yourself
# see: `Contact#contacts`
def contact_contacts
@contact_contacts ||= if @person == current_user.person
current_user.contact_people
else
contact = current_user.contact_for(@person)
contact.try(:contacts) || Contact.none
end
end
def mark_corresponding_notifications_read
......
......@@ -18,7 +18,7 @@ class BasePresenter
end
def method_missing(method, *args)
@presentable.send(method, *args) if @presentable.respond_to?(method)
@presentable.public_send(method, *args)
end
class NilPresenter
......
......@@ -11,7 +11,7 @@ class PersonPresenter < BasePresenter
base_hash.merge({
relationship: relationship,
block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false,
contact: { id: current_user_person_contact.id },
contact: (!own_profile? && has_contact?) ? { id: current_user_person_contact.id } : false,
is_own_profile: own_profile?
})
end
......@@ -73,6 +73,10 @@ class PersonPresenter < BasePresenter
@contact ||= current_user.contact_for(@presentable)
end
def has_contact?
current_user_person_contact.present?
end
def is_blocked?
current_user_person_block.present?
end
......
class PhotoPresenter < BasePresenter
def base_hash
{ id: id,
guid: guid,
dimensions: {
h: height,
w: width
},
sizes: {
s: url(:thumb_small),
m: url(:thumb_medium),
l: url(:scaled_full)
}
}
end
end
class ProfilePresenter < BasePresenter
include PeopleHelper
def base_hash
{ id: id,
tags: tag_string,
......@@ -15,4 +17,8 @@ class ProfilePresenter < BasePresenter
avatar: AvatarPresenter.new(@presentable).base_hash,
})
end
def formatted_birthday
birthday_format(birthday) if birthday
end
end
......@@ -123,6 +123,13 @@ en:
helper:
is_sharing: "<%= name %> is sharing with you"
is_not_sharing: "<%= name %> is not sharing with you"
profile:
bio: 'Bio'
location: "Location"
gender: "Gender"
born: "Birthday"
photos: "Photos"
contacts: "Contacts"
conversation:
participants: "Participants"
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter