* 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
This commit is contained in:
parent
9a16560d8d
commit
2572fb77fc
13 changed files with 232 additions and 70 deletions
52
app/assets/javascripts/app/helpers/direction_detector.js
Normal file
52
app/assets/javascripts/app/helpers/direction_detector.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
(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);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
<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
|
||||
|
|
|
|||
16
app/presenters/photo_presenter.rb
Normal file
16
app/presenters/photo_presenter.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue