Merge branch 'master' of github.com:diaspora/diaspora into js-refactor-merged
Conflicts: app/views/status_messages/bookmarklet.html.haml config/assets.yml db/schema.rb public/javascripts/contact-edit.js public/javascripts/publisher.js public/javascripts/view.js
This commit is contained in:
commit
3ed50cab94
236 changed files with 3448 additions and 2304 deletions
6
Gemfile
6
Gemfile
|
|
@ -97,13 +97,15 @@ group :test, :development do
|
|||
gem 'linecache', '0.43', :platforms => :mri_18
|
||||
end
|
||||
gem 'launchy'
|
||||
gem 'jasmine', '1.0.2.1'
|
||||
gem 'jasmine', '1.1.0.rc3'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'mysql2', '0.2.6'
|
||||
gem 'pg'
|
||||
gem 'factory_girl_rails'
|
||||
gem 'fixture_builder', '0.2.2'
|
||||
gem 'selenium-webdriver', '0.2.2'
|
||||
gem 'selenium-webdriver', '2.4'
|
||||
gem 'capybara', '~> 0.3.9'
|
||||
gem 'cucumber-rails', '0.3.2'
|
||||
gem 'rspec', '>= 2.0.0'
|
||||
|
|
|
|||
17
Gemfile.lock
17
Gemfile.lock
|
|
@ -143,7 +143,7 @@ GEM
|
|||
ohai (>= 0.5.7)
|
||||
rest-client (< 1.7.0, >= 1.0.4)
|
||||
uuidtools
|
||||
childprocess (0.2.0)
|
||||
childprocess (0.2.1)
|
||||
ffi (~> 1.0.6)
|
||||
closure-compiler (1.1.1)
|
||||
cloudfiles (1.4.10)
|
||||
|
|
@ -225,11 +225,12 @@ GEM
|
|||
jammit (0.5.4)
|
||||
closure-compiler (>= 0.1.0)
|
||||
yui-compressor (>= 0.9.1)
|
||||
jasmine (1.0.2.1)
|
||||
json_pure (>= 1.4.3)
|
||||
jasmine (1.1.0.rc3)
|
||||
jasmine-core (>= 1.1.0.rc2)
|
||||
rack (>= 1.1)
|
||||
rspec (>= 1.3.1)
|
||||
selenium-webdriver (>= 0.1.3)
|
||||
jasmine-core (1.1.0.rc3)
|
||||
json (1.4.6)
|
||||
json_pure (1.5.3)
|
||||
launchy (2.0.3)
|
||||
|
|
@ -318,6 +319,7 @@ GEM
|
|||
oa-openid (= 0.2.6)
|
||||
open4 (1.1.0)
|
||||
orm_adapter (0.0.5)
|
||||
pg (0.11.0)
|
||||
polyglot (0.3.2)
|
||||
pyu-ruby-sasl (0.0.3.3)
|
||||
rack (1.2.3)
|
||||
|
|
@ -399,8 +401,8 @@ GEM
|
|||
rubyntlm (0.1.1)
|
||||
rubyzip (0.9.4)
|
||||
sass (3.1.4)
|
||||
selenium-webdriver (0.2.2)
|
||||
childprocess (>= 0.1.9)
|
||||
selenium-webdriver (2.4.0)
|
||||
childprocess (>= 0.2.1)
|
||||
ffi (>= 1.0.7)
|
||||
json_pure
|
||||
rubyzip
|
||||
|
|
@ -484,7 +486,7 @@ DEPENDENCIES
|
|||
http_accept_language!
|
||||
i18n-inflector-rails (~> 1.0)
|
||||
jammit (= 0.5.4)
|
||||
jasmine (= 1.0.2.1)
|
||||
jasmine (= 1.1.0.rc3)
|
||||
json (= 1.4.6)
|
||||
jwt!
|
||||
launchy
|
||||
|
|
@ -497,6 +499,7 @@ DEPENDENCIES
|
|||
oauth2-provider (= 0.0.16)
|
||||
ohai (= 0.5.8)
|
||||
omniauth (= 0.2.6)
|
||||
pg
|
||||
rails (= 3.0.9)
|
||||
rails-i18n
|
||||
rcov
|
||||
|
|
@ -511,7 +514,7 @@ DEPENDENCIES
|
|||
ruby-debug
|
||||
ruby-debug19
|
||||
sass (= 3.1.4)
|
||||
selenium-webdriver (= 0.2.2)
|
||||
selenium-webdriver (= 2.4)
|
||||
settingslogic (= 2.0.6)
|
||||
sod!
|
||||
sqlite3
|
||||
|
|
|
|||
|
|
@ -8,30 +8,62 @@ class AdminsController < ApplicationController
|
|||
@users = params[:user].empty? ? [] : User.where(params[:user])
|
||||
end
|
||||
|
||||
def add_invites
|
||||
user = User.find(params[:user_id])
|
||||
|
||||
if user.increment(:invites, 10).save
|
||||
flash[:notice] = "Great Job!"
|
||||
else
|
||||
flash[:alert] = "there was a problem adding invites"
|
||||
def admin_inviter
|
||||
user = User.find_by_email params[:idenitifer]
|
||||
unless user
|
||||
Invitation.create(:service => 'email', :identifer => params[:identifier], :admin => true)
|
||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
||||
end
|
||||
|
||||
redirect_to user_search_path(:user => { :id => user.id })
|
||||
end
|
||||
|
||||
def admin_inviter
|
||||
opts = {:service => 'email', :identifier => params[:identifier]}
|
||||
existing_user = Invitation.find_existing_user('email', params[:identifier])
|
||||
opts.merge!(:existing_user => existing_user) if existing_user
|
||||
Invitation.create_invitee(opts)
|
||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
||||
redirect_to user_search_path
|
||||
end
|
||||
|
||||
def stats
|
||||
@popular_tags = ActsAsTaggableOn::Tagging.joins(:tag).limit(15).count(:group => :tag, :order => 'count(taggings.id) DESC')
|
||||
@new_posts = Post.where(:type => ['StatusMessage','ActivityStreams::Photo'],
|
||||
:public => true).order('created_at DESC').limit(15).all
|
||||
|
||||
case params[:range]
|
||||
when "week"
|
||||
range = 1.week
|
||||
@segment = "week"
|
||||
when "2weeks"
|
||||
range = 2.weeks
|
||||
@segment = "2 week"
|
||||
when "month"
|
||||
range = 1.month
|
||||
@segment = "month"
|
||||
else
|
||||
range = 1.day
|
||||
@segment = "daily"
|
||||
end
|
||||
|
||||
[Post, Comment, AspectMembership, User].each do |model|
|
||||
create_hash(model, :range => range)
|
||||
end
|
||||
|
||||
@posts_per_day = Post.count(:group => "DATE(created_at)", :conditions => ["created_at >= ?", Date.today - 21.days], :order => "DATE(created_at) ASC")
|
||||
@most_posts_within = @posts_per_day.values.max.to_f
|
||||
|
||||
@user_count = User.count
|
||||
|
||||
#@posts[:new_public] = Post.where(:type => ['StatusMessage','ActivityStreams::Photo'],
|
||||
# :public => true).order('created_at DESC').limit(15).all
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
def percent_change(today, yesterday)
|
||||
sprintf( "%0.02f", ((today-yesterday) / yesterday.to_f)*100).to_f
|
||||
end
|
||||
|
||||
def create_hash(model, opts={})
|
||||
opts[:range] ||= 1.day
|
||||
plural = model.to_s.underscore.pluralize
|
||||
eval(<<DATA
|
||||
@#{plural} = {
|
||||
:day_before => #{model}.where(:created_at => ((Time.now.midnight - #{opts[:range]*2})..Time.now.midnight - #{opts[:range]})).count,
|
||||
:yesterday => #{model}.where(:created_at => ((Time.now.midnight - #{opts[:range]})..Time.now.midnight)).count
|
||||
}
|
||||
@#{plural}[:change] = percent_change(@#{plural}[:yesterday], @#{plural}[:day_before])
|
||||
DATA
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class AspectsController < ApplicationController
|
|||
all_selected_people = Person.joins(:contacts => :aspect_memberships).
|
||||
where(:contacts => {:user_id => current_user.id},
|
||||
:aspect_memberships => {:aspect_id => aspect_ids})
|
||||
@selected_people = all_selected_people.select("DISTINCT people.*").order('RAND()').limit(20).includes(:profile)
|
||||
@selected_people = all_selected_people.select("DISTINCT people.*").includes(:profile)
|
||||
end
|
||||
|
||||
@aspect_ids = @aspects.map { |a| a.id }
|
||||
|
|
@ -45,7 +45,7 @@ class AspectsController < ApplicationController
|
|||
if params[:only_posts]
|
||||
render :partial => 'shared/stream', :locals => {:posts => @posts}
|
||||
else
|
||||
@contact_count = current_user.contacts.receiving.count
|
||||
@contact_count = @selected_people.count
|
||||
|
||||
@aspect = :all unless params[:a_ids]
|
||||
@aspect ||= @aspects.first # used in mobile
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class CommentsController < ApplicationController
|
|||
def index
|
||||
@post = current_user.find_visible_post_by_id(params[:post_id])
|
||||
if @post
|
||||
@comments = @post.comments.includes(:author => :profile)
|
||||
@comments = @post.comments.includes(:author => :profile).order('created_at ASC')
|
||||
render :layout => false
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound.new
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ class ContactsController < ApplicationController
|
|||
format.html { @contacts = sort_and_paginate_profiles(@contacts) }
|
||||
format.mobile { @contacts = sort_and_paginate_profiles(@contacts) }
|
||||
format.json {
|
||||
@people = Person.joins(:contacts => :aspect_memberships).
|
||||
@people = Person.for_json.joins(:contacts => :aspect_memberships).
|
||||
where(:contacts => { :user_id => current_user.id },
|
||||
:aspect_memberships => { :aspect_id => params[:aspect_ids] })
|
||||
|
||||
render :json => @people.includes(:profile).to_json
|
||||
render :json => @people.to_json
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,16 +28,20 @@ class ConversationsController < ApplicationController
|
|||
|
||||
params[:conversation][:participant_ids] = person_ids | [current_user.person.id]
|
||||
params[:conversation][:author] = current_user.person
|
||||
message_text = params[:conversation].delete(:text)
|
||||
params[:conversation][:messages_attributes] = [ {:author => current_user.person, :text => message_text }]
|
||||
|
||||
if @conversation = Conversation.create(params[:conversation])
|
||||
@conversation = Conversation.new(params[:conversation])
|
||||
if @conversation.save
|
||||
Postzord::Dispatch.new(current_user, @conversation).post
|
||||
|
||||
flash[:notice] = I18n.t('conversations.create.sent')
|
||||
if params[:profile]
|
||||
redirect_to person_path(params[:profile])
|
||||
else
|
||||
redirect_to conversations_path(:conversation_id => @conversation.id)
|
||||
end
|
||||
else
|
||||
flash[:error] = I18n.t('conversations.create.fail')
|
||||
end
|
||||
if params[:profile]
|
||||
redirect_to person_path(params[:profile])
|
||||
else
|
||||
redirect_to conversations_path(:conversation_id => @conversation.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,69 +5,49 @@
|
|||
class InvitationsController < Devise::InvitationsController
|
||||
|
||||
before_filter :check_token, :only => [:edit]
|
||||
before_filter :check_if_invites_open, :only =>[:create]
|
||||
|
||||
def new
|
||||
@sent_invitations = current_user.invitations_from_me.includes(:recipient)
|
||||
render :layout => false
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render :layout => false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if !AppConfig[:open_invitations] && current_user.invites == 0
|
||||
flash[:error] = I18n.t 'invitations.create.no_more'
|
||||
redirect_to :back
|
||||
return
|
||||
end
|
||||
aspect = params[:user].delete(:aspects)
|
||||
message = params[:user].delete(:invite_messages)
|
||||
emails = params[:user][:email].to_s.gsub(/\s/, '').split(/, */)
|
||||
aspect_id = params[:user].delete(:aspects)
|
||||
message = params[:user].delete(:invite_messages)
|
||||
emails = params[:user][:email].to_s.gsub(/\s/, '').split(/, */)
|
||||
#NOTE should we try and find users by email here? probs
|
||||
aspect = current_user.aspects.find(aspect_id)
|
||||
|
||||
good_emails, bad_emails = emails.partition{|e| e.try(:match, Devise.email_regexp)}
|
||||
invites = Invitation.batch_invite(emails, :message => message, :sender => current_user, :aspect => aspect, :service => 'email')
|
||||
|
||||
if good_emails.include?(current_user.email)
|
||||
if good_emails.length == 1
|
||||
flash[:error] = I18n.t 'invitations.create.own_address'
|
||||
redirect_to :back
|
||||
return
|
||||
else
|
||||
bad_emails.push(current_user.email)
|
||||
good_emails.delete(current_user.email)
|
||||
end
|
||||
end
|
||||
|
||||
good_emails.each{|e| Resque.enqueue(Job::InviteUserByEmail, current_user.id, e, aspect, message)}
|
||||
|
||||
if bad_emails.any?
|
||||
flash[:error] = I18n.t('invitations.create.sent') + good_emails.join(', ') + " "+ I18n.t('invitations.create.rejected') + bad_emails.join(', ')
|
||||
else
|
||||
flash[:notice] = I18n.t('invitations.create.sent') + good_emails.join(', ')
|
||||
end
|
||||
flash[:notice] = extract_messages(invites)
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
invitation_token = params[:user][:invitation_token]
|
||||
|
||||
if invitation_token.nil? || invitation_token.blank?
|
||||
raise I18n.t('invitations.check_token.not_found')
|
||||
redirect_to :back, :error => I18n.t('invitations.check_token.not_found')
|
||||
return
|
||||
end
|
||||
user = User.find_by_invitation_token(params[:user][:invitation_token])
|
||||
|
||||
user = User.find_by_invitation_token!(invitation_token)
|
||||
|
||||
user.accept_invitation!(params[:user])
|
||||
user.seed_aspects
|
||||
rescue Exception => e #What exception is this trying to rescue? If it is ActiveRecord::NotFound, we should say so.
|
||||
user = nil
|
||||
record = e.record
|
||||
record.errors.delete(:person)
|
||||
|
||||
flash[:error] = record.errors.full_messages.join(", ")
|
||||
end
|
||||
|
||||
if user
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
sign_in_and_redirect(:user, user)
|
||||
if user.persisted? && user.person && user.person.persisted?
|
||||
user.seed_aspects
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
sign_in_and_redirect(:user, user)
|
||||
else
|
||||
redirect_to accept_user_invitation_path(
|
||||
:invitation_token => params[:user][:invitation_token])
|
||||
redirect_to accept_user_invitation_path(:invitation_token => params[:user][:invitation_token]), :error => user.errors.full_messages.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -85,12 +65,42 @@ class InvitationsController < Devise::InvitationsController
|
|||
@resource = User.find_by_invitation_token(params[:invitation_token])
|
||||
render 'devise/mailer/invitation_instructions', :layout => false
|
||||
end
|
||||
protected
|
||||
|
||||
protected
|
||||
def check_token
|
||||
if User.find_by_invitation_token(params[:invitation_token]).nil?
|
||||
flash[:error] = I18n.t 'invitations.check_token.not_found'
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
def check_if_invites_open
|
||||
unless AppConfig[:open_invitations]
|
||||
flash[:error] = I18n.t 'invitations.create.no_more'
|
||||
redirect_to :back
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# @param invites [Array<Invitation>] Invitations to be sent.
|
||||
# @return [String] A full list of success and error messages.
|
||||
def extract_messages(invites)
|
||||
success_message = "Invites Successfully Sent to: "
|
||||
failure_message = "There was a problem with: "
|
||||
following_message = " already are on Diaspora, so you are now sharing with them."
|
||||
successes, failures = invites.partition{|x| x.persisted? }
|
||||
|
||||
followings, real_failures = failures.partition{|x| x.errors[:recipient].present? }
|
||||
|
||||
success_message += successes.map{|k| k.identifier }.to_sentence
|
||||
failure_message += real_failures.map{|k| k.identifier }.to_sentence
|
||||
following_message += followings.map{|k| k.identifier}.to_sentence
|
||||
|
||||
messages = []
|
||||
messages << success_message if successes.present?
|
||||
messages << failure_message if failures.present?
|
||||
messages << following_message if followings.present?
|
||||
|
||||
messages.join('\n')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@ class MessagesController < ApplicationController
|
|||
if message.save
|
||||
Rails.logger.info("event=create type=comment user=#{current_user.diaspora_handle} status=success message=#{message.id} chars=#{params[:message][:text].length}")
|
||||
Postzord::Dispatch.new(current_user, message).post
|
||||
|
||||
redirect_to conversations_path(:conversation_id => cnv.id)
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
flash[:error] = I18n.t('conversations.new_message.fail')
|
||||
end
|
||||
redirect_to conversations_path(:conversation_id => cnv.id)
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class NotificationsController < VannaController
|
|||
end
|
||||
notifications.each do |n|
|
||||
n[:actors] = n.actors
|
||||
n[:translation] = object_link(n, n.actors.map { |a| person_link(a) })
|
||||
n[:translation] = notification_message_for(n)
|
||||
n[:translation_key] = n.popup_translation_key
|
||||
n[:target] = n.translation_key == "notifications.mentioned" ? n.target.post : n.target
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,18 @@ class PeopleController < ApplicationController
|
|||
render :json => @people
|
||||
end
|
||||
|
||||
format.all do
|
||||
format.html do
|
||||
#only do it if it is an email address
|
||||
if params[:q].try(:match, Devise.email_regexp)
|
||||
people = Person.where(:diaspora_handle => params[:q])
|
||||
webfinger(params[:q]) if people.empty?
|
||||
else
|
||||
people = Person.search(params[:q], current_user)
|
||||
end
|
||||
@people = people.paginate( :page => params[:page], :per_page => 15)
|
||||
@hashes = hashes_for_people(@people, @aspects)
|
||||
end
|
||||
format.mobile do
|
||||
#only do it if it is an email address
|
||||
if params[:q].try(:match, Devise.email_regexp)
|
||||
people = Person.where(:diaspora_handle => params[:q])
|
||||
|
|
@ -68,7 +79,7 @@ class PeopleController < ApplicationController
|
|||
@person = Person.find_from_id_or_username(params)
|
||||
|
||||
if remote_profile_with_no_user_session?
|
||||
raise ActiveRecord::RecordNotFound
|
||||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
@post_type = :all
|
||||
|
|
@ -146,8 +157,12 @@ class PeopleController < ApplicationController
|
|||
|
||||
def aspect_membership_dropdown
|
||||
@person = Person.find(params[:person_id])
|
||||
@contact = current_user.contact_for(@person) || Contact.new
|
||||
render :partial => 'aspect_memberships/aspect_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left'}
|
||||
if @person == current_user.person
|
||||
render :text => I18n.t('people.person.thats_you')
|
||||
else
|
||||
@contact = current_user.contact_for(@person) || Contact.new
|
||||
render :partial => 'aspect_membership_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left'}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class PhotosController < ApplicationController
|
|||
format.html do
|
||||
flash[:notice] = I18n.t 'photos.destroy.notice'
|
||||
if photo.status_message_guid
|
||||
respond_with photo, :location => photo.status_message
|
||||
respond_with photo, :location => post_path(photo.status_message)
|
||||
else
|
||||
respond_with photo, :location => person_photos_path(current_user.person)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class PostsController < ApplicationController
|
|||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.all{ }
|
||||
format.xml{ render :xml => @post.to_diaspora_xml }
|
||||
format.any{}
|
||||
end
|
||||
|
||||
else
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
def create
|
||||
@user = User.build(params[:user])
|
||||
@user.invites = 20
|
||||
if @user.save
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
@user.seed_aspects
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
class ServicesController < ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
|
||||
respond_to :html
|
||||
respond_to :json, :only => :inviter
|
||||
|
||||
def index
|
||||
@services = current_user.services
|
||||
end
|
||||
|
|
@ -45,27 +48,58 @@ class ServicesController < ApplicationController
|
|||
end
|
||||
|
||||
def finder
|
||||
@finder = true
|
||||
service = current_user.services.where(:type => "Services::#{params[:provider].titleize}").first
|
||||
@friends = service ? service.finder(:remote => params[:remote]) : []
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
def inviter
|
||||
@uid = params[:uid]
|
||||
|
||||
if i_id = params[:invitation_id]
|
||||
invited_user = Invitation.find(i_id).recipient
|
||||
invite = Invitation.find(i_id)
|
||||
invited_user = invite.recipient
|
||||
else
|
||||
invited_user = current_user.invite_user(params[:aspect_id], params[:provider], @uid)
|
||||
invite = Invitation.create(:service => params[:provider], :identifier => @uid, :sender => current_user, :aspect => current_user.aspects.find(params[:aspect_id]))
|
||||
invited_user = invite.attach_recipient!
|
||||
end
|
||||
|
||||
@subject = t('services.inviter.join_me_on_diaspora')
|
||||
@message = <<MSG
|
||||
#to make sure a friend you just invited from facebook shows up as invited
|
||||
service = current_user.services.where(:type => "Services::Facebook").first
|
||||
su = ServiceUser.where(:service_id => service.id, :uid => @uid).first
|
||||
su.attach_local_models
|
||||
su.save
|
||||
|
||||
respond_to do |format|
|
||||
format.html{ invite_redirect_url(invite, invited_user, su)}
|
||||
format.json{ render :json => invite_redirect_json(invite, invited_user, su) }
|
||||
end
|
||||
end
|
||||
|
||||
def facebook_message_url(user, facebook_uid)
|
||||
subject = t('services.inviter.join_me_on_diaspora')
|
||||
message = <<MSG
|
||||
#{t('services.inviter.click_link_to_accept_invitation')}:
|
||||
\n
|
||||
\n
|
||||
#{accept_invitation_url(invited_user, :invitation_token => invited_user.invitation_token)}
|
||||
#{accept_invitation_url(user, :invitation_token => user.invitation_token)}
|
||||
MSG
|
||||
redirect_to "https://www.facebook.com/?compose=1&id=#{@uid}&subject=#{@subject}&message=#{@message}&sk=messages"
|
||||
"https://www.facebook.com/?compose=1&id=#{facebook_uid}&subject=#{subject}&message=#{message}&sk=messages"
|
||||
end
|
||||
|
||||
def invite_redirect_json(invite, user, service_user)
|
||||
if invite.email_like_identifer
|
||||
{:message => t("invitations.create.sent") + service_user.name }
|
||||
else
|
||||
{:url => facebook_message_url(user, service_user.uid)}
|
||||
end
|
||||
end
|
||||
|
||||
def invite_redirect_url(invite, user, service_user)
|
||||
if invite.email_like_identifer
|
||||
redirect_to(friend_finder_path(:provider => 'facebook'), :notice => "you re-invited #{service_user.name}")
|
||||
else
|
||||
redirect_to(facebook_message_url(user, service_user.uid))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -65,17 +65,28 @@ module AspectGlobalHelper
|
|||
end
|
||||
end
|
||||
|
||||
def aspect_dropdown_list_item(aspect, contact, person)
|
||||
checked = (contact.persisted? && contact.aspect_memberships.detect{ |am| am.aspect_id == aspect.id})
|
||||
def aspect_membership_dropdown(contact, person, hang, aspect=nil)
|
||||
selected_aspects = all_aspects.select{|aspect| contact.in_aspect?(aspect) }
|
||||
|
||||
render "shared/aspect_dropdown",
|
||||
:selected_aspects => selected_aspects,
|
||||
:person => person,
|
||||
:hang => hang,
|
||||
:dropdown_class => "aspect_membership"
|
||||
end
|
||||
|
||||
def aspect_dropdown_list_item(aspect, checked)
|
||||
klass = checked ? "selected" : ""
|
||||
|
||||
str = <<LISTITEM
|
||||
<li data-aspect_id=#{aspect.id} class='#{klass}'>
|
||||
<img src='/images/icons/check_yes_ok.png' width=18 height=18 class='check'/>
|
||||
<img src='/images/icons/check_yes_ok_white.png' width=18 height=18 class='checkWhite'/>
|
||||
#{aspect.name}
|
||||
</li>
|
||||
LISTITEM
|
||||
str.html_safe
|
||||
end
|
||||
|
||||
def dropdown_may_create_new_aspect
|
||||
@aspect == :profile || @aspect == :tag || @aspect == :search || @aspect == :notification
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ module NotificationsHelper
|
|||
number_of_actors = actors.count
|
||||
sentence_translations = {:two_words_connector => " #{t('notifications.index.and')} ", :last_word_connector => ", #{t('notifications.index.and')} " }
|
||||
actor_links = actors.collect{ |person|
|
||||
person_link(person, :class => 'hovercardable', :what => 'thefuck' )
|
||||
person_link(person, :class => 'hovercardable')
|
||||
}
|
||||
|
||||
if number_of_actors < 4
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
module NotifierHelper
|
||||
|
||||
# @param post [Post] The post object.
|
||||
# @param opts [Hash] Optional hash. Accepts :length and :process_newlines parameters.
|
||||
# @return [String] The truncated and formatted post.
|
||||
def post_message(post, opts={})
|
||||
opts[:length] ||= 200
|
||||
if post.respond_to? :formatted_message
|
||||
|
|
@ -9,4 +13,23 @@ module NotifierHelper
|
|||
I18n.translate 'notifier.a_post_you_shared'
|
||||
end
|
||||
end
|
||||
|
||||
# @param comment [Comment] The comment to process.
|
||||
# @param opts [Hash] Optional hash. Accepts :length and :process_newlines parameters.
|
||||
# @return [String] The truncated and formatted comment.
|
||||
def comment_message(comment, opts={})
|
||||
opts[:length] ||= 600
|
||||
text = truncate(@comment.text, :length => opts[:length])
|
||||
text = process_newlines(text) if opts[:process_newlines]
|
||||
text
|
||||
end
|
||||
|
||||
def invite_email_title
|
||||
names = @invites.collect{|x| x.sender.person.name}.uniq
|
||||
if @invites.empty? && names.empty?
|
||||
"Accept Your Diaspora* invite!"
|
||||
else
|
||||
"#{names.to_sentence} invited you to Diaspora*"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,18 +27,14 @@ module PeopleHelper
|
|||
I18n.l bday, :format => I18n.t('date.formats.birthday_with_year')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def person_link(person, opts={})
|
||||
opts[:class] ||= ""
|
||||
opts[:class] << " self" if defined?(user_signed_in?) && user_signed_in? && current_user.person == person
|
||||
remote_or_hovercard_link = "/people/#{person.id}".html_safe
|
||||
if person.local?
|
||||
"<a data-hovercard='#{remote_or_hovercard_link}' href='/u/#{person.diaspora_handle.split('@')[0]}' class='#{opts[:class]}'>#{h(person.name)}</a>".html_safe
|
||||
else
|
||||
"<a href='#{remote_or_hovercard_link}' data-hovercard='#{remote_or_hovercard_link}' class='#{opts[:class]}' >#{h(person.name)}</a>".html_safe
|
||||
end
|
||||
"<a data-hovercard='#{remote_or_hovercard_link}' #{person_href(person)} class='#{opts[:class]}'>#{h(person.name)}</a>".html_safe
|
||||
end
|
||||
|
||||
|
||||
def person_image_tag(person, size=nil)
|
||||
size ||= :thumb_small
|
||||
"<img alt=\"#{h(person.name)}\" class=\"avatar\" data-person_id=\"#{person.id}\" src=\"#{person.profile.image_url(size)}\" title=\"#{h(person.name)} (#{h(person.diaspora_handle)})\">".html_safe
|
||||
|
|
@ -49,16 +45,20 @@ module PeopleHelper
|
|||
if opts[:to] == :photos
|
||||
link_to person_image_tag(person, opts[:size]), person_photos_path(person)
|
||||
else
|
||||
if person.local?
|
||||
"<a href='/u/#{person.diaspora_handle.split('@')[0]}' class='#{opts[:class]}'>
|
||||
#{person_image_tag(person, opts[:size])}
|
||||
</a>".html_safe
|
||||
else
|
||||
"<a href='/people/#{person.id}'>
|
||||
#{person_image_tag(person, opts[:size])}
|
||||
</a>".html_safe
|
||||
end
|
||||
"<a #{person_href(person)} class='#{opts[:class]}'>
|
||||
#{person_image_tag(person, opts[:size])}
|
||||
</a>".html_safe
|
||||
end
|
||||
end
|
||||
|
||||
def person_href(person)
|
||||
if person.local?
|
||||
username = person.diaspora_handle.split('@')[0]
|
||||
unless username.include?('.')
|
||||
return "href='/u/#{person.diaspora_handle.split('@')[0]}'"
|
||||
end
|
||||
end
|
||||
return "href='/people/#{person.id}'"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,16 +1,6 @@
|
|||
module ServicesHelper
|
||||
GSUB_THIS = "FIUSDHVIUSHDVIUBAIUHAPOIUXJM"
|
||||
@@contact_proxy = Contact.new(:aspects => [])
|
||||
def contact_proxy(friend)
|
||||
friend.contact || Contact.new(:person => friend.person)
|
||||
end
|
||||
|
||||
# This method memoizes the facebook invite form in order to avoid the overhead of rendering it on every post.
|
||||
# @param [ServiceUser] friend
|
||||
# @return [String] The HTML for the form.
|
||||
def facebook_invite_form friend
|
||||
@form ||= controller.render_to_string(
|
||||
:partial => 'services/facebook_invite',
|
||||
:locals => {:uid => GSUB_THIS})
|
||||
@form.gsub(GSUB_THIS, friend.uid).html_safe
|
||||
friend.contact || @@contact_proxy.dup.tap{|c| c.person = friend.person}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
5
app/mailers/diaspora_devise_mailer.rb
Normal file
5
app/mailers/diaspora_devise_mailer.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class DiasporaDeviseMailer < Devise::Mailer
|
||||
include NotifierHelper
|
||||
default :from => AppConfig[:smtp_sender_address]
|
||||
|
||||
end
|
||||
|
|
@ -74,7 +74,7 @@ class Notifier < ActionMailer::Base
|
|||
I18n.with_locale(@receiver.language) do
|
||||
mail(:from => "\"#{@sender.name} (Diaspora)\" <#{AppConfig[:smtp_sender_address]}>",
|
||||
:to => "\"#{@receiver.name}\" <#{@receiver.email}>",
|
||||
:subject => "Re: #{post_message(@comment.parent, :length => TRUNCATION_LEN)}")
|
||||
:subject => "Re: #{comment_email_subject}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -89,13 +89,16 @@ class Notifier < ActionMailer::Base
|
|||
log_mail(recipient_id, sender_id, 'comment_on_post')
|
||||
|
||||
I18n.with_locale(@receiver.language) do
|
||||
subject_message = post_message(@comment.parent, :length => TRUNCATION_LEN)
|
||||
mail(:from => "\"#{@sender.name} (Diaspora)\" <#{AppConfig[:smtp_sender_address]}>",
|
||||
:to => "\"#{@receiver.name}\" <#{@receiver.email}>",
|
||||
:subject => "Re: #{subject_message}")
|
||||
:subject => "Re: #{comment_email_subject}")
|
||||
end
|
||||
end
|
||||
|
||||
def comment_email_subject
|
||||
truncate(@comment.parent.comment_email_subject, :length => TRUNCATION_LEN)
|
||||
end
|
||||
|
||||
def private_message(recipient_id, sender_id, message_id)
|
||||
@receiver = User.find_by_id(recipient_id)
|
||||
@sender = Person.find_by_id(sender_id)
|
||||
|
|
|
|||
|
|
@ -53,5 +53,9 @@ class ActivityStreams::Photo < Post
|
|||
# A better solution is needed.
|
||||
# @return [Boolean] true
|
||||
def activity_streams?; true; end
|
||||
|
||||
def comment_email_subject
|
||||
I18n.t("photos.comment_email_subject", :name => author.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,16 @@ class Contact < ActiveRecord::Base
|
|||
self.sharing && self.receiving
|
||||
end
|
||||
|
||||
def in_aspect? aspect
|
||||
if aspect_memberships.loaded?
|
||||
aspect_memberships.detect{ |am| am.aspect_id == aspect.id }
|
||||
elsif aspects.loaded?
|
||||
aspects.detect{ |a| a.id == aspect.id }
|
||||
else
|
||||
AspectMembership.exists?(:contact_id => self.id, :aspect_id => aspect.id)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def not_contact_for_self
|
||||
if person_id && person.owner == user
|
||||
|
|
|
|||
|
|
@ -15,15 +15,7 @@ class Conversation < ActiveRecord::Base
|
|||
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
def self.create(opts={})
|
||||
opts = opts.dup
|
||||
msg_opts = {:author => opts[:author], :text => opts.delete(:text)}
|
||||
|
||||
cnv = super(opts)
|
||||
message = Message.new(msg_opts.merge({:conversation_id => cnv.id}))
|
||||
message.save
|
||||
cnv
|
||||
end
|
||||
accepts_nested_attributes_for :messages
|
||||
|
||||
def recipients
|
||||
self.participants - [self.author]
|
||||
|
|
|
|||
|
|
@ -1,106 +1,177 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
#
|
||||
|
||||
class Invitation < ActiveRecord::Base
|
||||
|
||||
belongs_to :sender, :class_name => 'User'
|
||||
belongs_to :recipient, :class_name => 'User'
|
||||
belongs_to :aspect
|
||||
|
||||
validates_presence_of :sender, :recipient, :aspect
|
||||
attr_accessible :sender, :recipient, :aspect, :service, :identifier, :admin, :message
|
||||
|
||||
def self.invite(opts = {})
|
||||
opts[:identifier].downcase! if opts[:identifier]
|
||||
return false if opts[:identifier] == opts[:from].email
|
||||
before_validation :set_email_as_default_service
|
||||
|
||||
existing_user = self.find_existing_user(opts[:service], opts[:identifier])
|
||||
# before_create :share_with_exsisting_user, :if => :recipient_id?
|
||||
validates_presence_of :identifier, :service
|
||||
validate :valid_identifier?
|
||||
validate :recipient_not_on_pod?
|
||||
validates_presence_of :sender, :aspect, :unless => :admin?
|
||||
validate :ensure_not_inviting_self, :on => :create, :unless => :admin?
|
||||
validate :sender_owns_aspect?, :unless => :admin?
|
||||
validates_uniqueness_of :sender_id, :scope => [:identifier, :service], :unless => :admin?
|
||||
|
||||
if existing_user
|
||||
if opts[:from].contact_for(opts[:from].person)
|
||||
raise "You are already connceted to this person"
|
||||
elsif not existing_user.invited?
|
||||
opts[:from].share_with(existing_user.person, opts[:into])
|
||||
return
|
||||
elsif Invitation.where(:sender_id => opts[:from].id, :recipient_id => existing_user.id).first
|
||||
raise "You already invited this person"
|
||||
end
|
||||
after_create :queue_send! #TODO make this after_commit :queue_saved!, :on => :create
|
||||
|
||||
|
||||
# @note options hash is passed through to [Invitation.new]
|
||||
# @see [Invitation.new]
|
||||
#
|
||||
# @param [Array<String>] emails
|
||||
# @option opts [User] :sender
|
||||
# @option opts [Aspect] :aspect
|
||||
# @option opts [String] :service
|
||||
# @return [Array<Invitation>] An array of [Invitation] models
|
||||
# the valid ones are saved, and the invalid ones are not.
|
||||
def self.batch_invite(emails, opts)
|
||||
|
||||
users_on_pod = User.where(:email => emails, :invitation_token => nil)
|
||||
|
||||
#share with anyone whose email you entered who is on the pod
|
||||
users_on_pod.each{|u| opts[:sender].share_with(u.person, opts[:aspect])}
|
||||
|
||||
emails.map! do |e|
|
||||
user = users_on_pod.find{|u| u.email == e}
|
||||
Invitation.create(opts.merge(:identifier => e, :recipient => user))
|
||||
end
|
||||
opts[:existing_user] = existing_user
|
||||
create_invitee(opts)
|
||||
emails
|
||||
end
|
||||
|
||||
def self.find_existing_user(service, identifier)
|
||||
existing_user = User.where(:invitation_service => service,
|
||||
:invitation_identifier => identifier).first
|
||||
if service == 'email'
|
||||
existing_user ||= User.where(:email => identifier).first
|
||||
else
|
||||
existing_user ||= User.joins(:services).where(:services => {:type => "Services::#{service.titleize}", :uid => identifier}).first
|
||||
end
|
||||
|
||||
existing_user
|
||||
# Downcases the incoming service identifier and assigns it
|
||||
#
|
||||
# @param ident [String] Service identifier
|
||||
# @see super
|
||||
def identifier=(ident)
|
||||
ident.downcase! if ident
|
||||
super
|
||||
end
|
||||
|
||||
def self.new_user_by_service_and_identifier(service, identifier)
|
||||
result = User.new()
|
||||
result.invitation_service = service
|
||||
result.invitation_identifier = identifier
|
||||
result.email = identifier if service == 'email'
|
||||
result.valid?
|
||||
result
|
||||
# Determine if we want to skip emailing the recipient.
|
||||
#
|
||||
# @return [Boolean]
|
||||
# @return [void]
|
||||
def skip_email?
|
||||
!email_like_identifer
|
||||
end
|
||||
|
||||
def self.create_invitee(opts = {})
|
||||
invitee = opts[:existing_user] || new_user_by_service_and_identifier(opts[:service], opts[:identifier])
|
||||
return invitee if opts[:service] == 'email' && !opts[:identifier].match(Devise.email_regexp)
|
||||
invitee.invites = opts[:invites] || 10
|
||||
if invitee.new_record?
|
||||
invitee.errors.clear
|
||||
invitee.serialized_private_key = User.generate_key if invitee.serialized_private_key.blank?
|
||||
invitee.send(:generate_invitation_token)
|
||||
elsif invitee.invitation_token.nil?
|
||||
return invitee
|
||||
# Attach a recipient [User] to the [Invitation] unless
|
||||
# there is one already present.
|
||||
#
|
||||
# @return [User] The recipient.
|
||||
def attach_recipient!
|
||||
unless self.recipient.present?
|
||||
self.recipient = User.find_or_create_by_invitation(self)
|
||||
self.save
|
||||
end
|
||||
|
||||
if opts[:from]
|
||||
invitee.save(:validate => false)
|
||||
Invitation.create!(:sender => opts[:from],
|
||||
:recipient => invitee,
|
||||
:aspect => opts[:into],
|
||||
:message => opts[:message])
|
||||
|
||||
opts[:from].invites -= 1 unless opts[:from].invites == 0
|
||||
opts[:from].save!
|
||||
invitee.reload
|
||||
end
|
||||
invitee.skip_invitation = (opts[:service] != 'email')
|
||||
invitee.invite!
|
||||
log_string = "event=invitation_sent to=#{opts[:identifier]} service=#{opts[:service]} "
|
||||
log_string << "inviter=#{opts[:from].diaspora_handle} inviter_uid=#{opts[:from].id} inviter_created_at_unix=#{opts[:from].created_at.to_i}" if opts[:from]
|
||||
Rails.logger.info(log_string)
|
||||
invitee
|
||||
self.recipient
|
||||
end
|
||||
|
||||
def resend
|
||||
# Find or create user, and send that resultant User an
|
||||
# invitation.
|
||||
#
|
||||
# @return [Invitation] self
|
||||
def send!
|
||||
self.attach_recipient!
|
||||
|
||||
# Sets an instance variable in User (set by devise invitable)
|
||||
# This determines whether an email should be sent to the recipient.
|
||||
recipient.skip_invitation = self.skip_email?
|
||||
|
||||
recipient.invite!
|
||||
|
||||
# Logging the invitation action
|
||||
log_hash = {:event => :invitation_sent, :to => self[:identifier], :service => self[:service]}
|
||||
log_hash.merge({:inviter => self.sender.diaspora_handle, :invitier_uid => self.sender.id, :inviter_created_at_unix => self.sender.created_at.to_i}) if self.sender
|
||||
Rails.logger.info(log_hash)
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def share_with!
|
||||
contact = sender.share_with(recipient.person, aspect)
|
||||
destroy if contact
|
||||
contact
|
||||
# @return [Invitation] self
|
||||
def resend
|
||||
self.send!
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def recipient_identifier
|
||||
if recipient.invitation_service == 'email'
|
||||
recipient.invitation_identifier
|
||||
elsif recipient.invitation_service == 'facebook'
|
||||
if su = ServiceUser.where(:uid => recipient.invitation_identifier).first
|
||||
case self.service
|
||||
when 'email'
|
||||
self.identifier
|
||||
when'facebook'
|
||||
if su = ServiceUser.where(:uid => self.identifier).first
|
||||
su.name
|
||||
else
|
||||
I18n.t('invitations.a_facebook_user')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def email_like_identifer
|
||||
case self.service
|
||||
when 'email'
|
||||
self.identifier
|
||||
when 'facebook'
|
||||
if username = ServiceUser.username_of_service_user_by_uid(self.identifier)
|
||||
unless username.include?('profile.php?')
|
||||
"#{username}@facebook.com"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def queue_send!
|
||||
unless self.recipient.present?
|
||||
Resque.enqueue(Job::Mail::InviteUserByEmail, self.id)
|
||||
end
|
||||
end
|
||||
|
||||
# @note before_save
|
||||
def set_email_as_default_service
|
||||
self.service ||= 'email'
|
||||
end
|
||||
|
||||
# @note Validation
|
||||
def ensure_not_inviting_self
|
||||
if self.identifier == self.sender.email
|
||||
errors[:base] << 'You can not invite yourself.'
|
||||
end
|
||||
end
|
||||
|
||||
# @note Validation
|
||||
def sender_owns_aspect?
|
||||
if self.sender_id != self.aspect.user_id
|
||||
errors[:base] << 'You do not own that aspect.'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def recipient_not_on_pod?
|
||||
return true if self.recipient.nil?
|
||||
if self.recipient.username?
|
||||
errors[:recipient] << "The user '#{self.identifier}' (#{self.recipient.diaspora_handle}) is already on this pod, so we sent them a share request"
|
||||
end
|
||||
end
|
||||
|
||||
# @note Validation
|
||||
def valid_identifier?
|
||||
return false unless self.identifier
|
||||
if self.service == 'email'
|
||||
unless self.identifier.match(Devise.email_regexp)
|
||||
errors[:base] << 'invalid email'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ module Job
|
|||
end
|
||||
unless response.success?
|
||||
pod = Pod.find_or_create_by_url(response.effective_url)
|
||||
log_line = "event=http_multi_fail sender_id=#{user_id} recipient_id=#{person.id} url=#{response.effective_url} response_code='#{response.code}' xml='#{Base64.decode64(enc_object_xml)}'"
|
||||
log_line = "event=http_multi_fail sender_id=#{user_id} recipient_id=#{person.id} url=#{response.effective_url} response_code='#{response.code}'"
|
||||
Rails.logger.info(log_line)
|
||||
pod.pod_stats.create(:error_message => log_line, :person_id => person.id, :error_code => response.code.to_i)
|
||||
failed_request_people << person.id
|
||||
16
app/models/job/mail/invite_user_by_email.rb
Normal file
16
app/models/job/mail/invite_user_by_email.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
|
||||
module Job
|
||||
module Mail
|
||||
class InviteUserByEmail < Base
|
||||
@queue = :mail
|
||||
def self.perform(invite_id)
|
||||
invite = Invitation.find(invite_id)
|
||||
invite.send!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -14,12 +14,23 @@ module Job
|
|||
socket_to_users(post, recipient_user_ids) if post.respond_to?(:socket_to_user)
|
||||
notify_mentioned_users(post)
|
||||
end
|
||||
|
||||
def self.create_visibilities(post, recipient_user_ids)
|
||||
contacts = Contact.where(:user_id => recipient_user_ids, :person_id => post.author_id)
|
||||
new_post_visibilities = contacts.map do |contact|
|
||||
PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
|
||||
|
||||
if postgres?
|
||||
# Take the naive approach to inserting our new visibilities for now.
|
||||
contacts.each do |contact|
|
||||
PostVisibility.find_or_create_by_contact_id_and_post_id(contact.id, post.id)
|
||||
end
|
||||
else
|
||||
# Use a batch insert on mySQL.
|
||||
new_post_visibilities = contacts.map do |contact|
|
||||
PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
|
||||
end
|
||||
PostVisibility.import(new_post_visibilities)
|
||||
end
|
||||
PostVisibility.import new_post_visibilities
|
||||
|
||||
end
|
||||
def self.socket_to_users(post, recipient_user_ids)
|
||||
recipient_user_ids.each do |id|
|
||||
|
|
@ -7,7 +7,7 @@ module Job
|
|||
class ResendInvitation < Base
|
||||
@queue = :mail
|
||||
def self.perform(invitation_id)
|
||||
inv = Invitation.where(:id => invitation_id).first
|
||||
inv = Invitation.find(invitation_id)
|
||||
inv.resend
|
||||
end
|
||||
end
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
|
||||
module Job
|
||||
class InviteUserByEmail < Base
|
||||
@queue = :mail
|
||||
def self.perform(sender_id, email, aspect_id, invite_message)
|
||||
user = User.find(sender_id)
|
||||
user.invite_user(aspect_id, 'email', email, invite_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
class NotVisibleError < RuntimeError; end
|
||||
class Message < ActiveRecord::Base
|
||||
include ROXML
|
||||
|
||||
|
|
@ -13,6 +14,8 @@ class Message < ActiveRecord::Base
|
|||
belongs_to :author, :class_name => 'Person'
|
||||
belongs_to :conversation, :touch => true
|
||||
|
||||
validates_presence_of :text
|
||||
|
||||
after_create do
|
||||
#sign comment as commenter
|
||||
self.author_signature = self.sign_with_key(self.author.owner.encryption_key) if self.author.owner
|
||||
|
|
@ -63,7 +66,7 @@ class Message < ActiveRecord::Base
|
|||
vis.save
|
||||
self
|
||||
else
|
||||
raise NotVisibleException("Attempting to access a ConversationVisibility that does not exist!")
|
||||
raise NotVisibleError.new("User #{user.id} with person #{user.person.id} is not allowed to see conversation #{conversation.id}!")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -71,6 +74,10 @@ class Message < ActiveRecord::Base
|
|||
Notifications::PrivateMessage unless user.person == person
|
||||
end
|
||||
|
||||
def formatted_message(opts={})
|
||||
opts[:plain_text] ? self.text: ERB::Util.h(self.text)
|
||||
end
|
||||
|
||||
private
|
||||
def participant_of_parent_conversation
|
||||
if self.parent && !self.parent.participants.include?(self.author)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class Person < ActiveRecord::Base
|
|||
|
||||
has_one :profile, :dependent => :destroy
|
||||
delegate :last_name, :to => :profile
|
||||
accepts_nested_attributes_for :profile
|
||||
|
||||
before_validation :downcase_diaspora_handle
|
||||
def downcase_diaspora_handle
|
||||
|
|
@ -45,12 +46,27 @@ class Person < ActiveRecord::Base
|
|||
scope :searchable, joins(:profile).where(:profiles => {:searchable => true})
|
||||
scope :remote, where('people.owner_id IS NULL')
|
||||
scope :local, where('people.owner_id IS NOT NULL')
|
||||
scope :for_json, select('DISTINCT people.id, people.diaspora_handle').includes(:profile)
|
||||
|
||||
def self.featured_users
|
||||
AppConfig[:featured_users].present? ? Person.where(:diaspora_handle => AppConfig[:featured_users]) : []
|
||||
end
|
||||
|
||||
|
||||
# Set a default of an empty profile when a new Person record is instantiated.
|
||||
# Passing :profile => nil to Person.new will instantiate a person with no profile.
|
||||
# Calling Person.new with a block:
|
||||
# Person.new do |p|
|
||||
# p.profile = nil
|
||||
# end
|
||||
# will not work! The nil profile will be overriden with an empty one.
|
||||
def initialize(params={})
|
||||
profile_set = params.has_key?(:profile) || params.has_key?("profile")
|
||||
params[:profile_attributes] = params.delete(:profile) if params.has_key?(:profile) && params[:profile].is_a?(Hash)
|
||||
super
|
||||
self.profile ||= Profile.new unless profile_set
|
||||
end
|
||||
|
||||
|
||||
def self.find_from_id_or_username(params)
|
||||
p = if params[:id].present?
|
||||
Person.where(:id => params[:id]).first
|
||||
|
|
@ -63,21 +79,15 @@ class Person < ActiveRecord::Base
|
|||
p
|
||||
end
|
||||
|
||||
|
||||
|
||||
def self.search_query_string(query)
|
||||
query = query.downcase
|
||||
like_operator = postgres? ? "ILIKE" : "LIKE"
|
||||
|
||||
if postgres?
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name ILIKE ? OR
|
||||
profiles.diaspora_handle ILIKE ?
|
||||
SQL
|
||||
else
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name LIKE ? OR
|
||||
people.diaspora_handle LIKE ?
|
||||
SQL
|
||||
end
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name #{like_operator} ? OR
|
||||
people.diaspora_handle #{like_operator} ?
|
||||
SQL
|
||||
|
||||
q_tokens = query.to_s.strip.gsub(/(\s|$|^)/) { "%#{$1}" }
|
||||
[where_clause, [q_tokens, q_tokens]]
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class Post < ActiveRecord::Base
|
|||
|
||||
local_post = Post.where(:guid => self.guid).first
|
||||
if local_post && local_post.author_id == self.author_id
|
||||
known_post = user.visible_posts.where(:guid => self.guid).first
|
||||
known_post = user.find_visible_post_by_id(self.guid, :key => :guid)
|
||||
if known_post
|
||||
if known_post.mutable?
|
||||
known_post.update_attributes(self.attributes)
|
||||
|
|
@ -117,6 +117,10 @@ class Post < ActiveRecord::Base
|
|||
false
|
||||
end
|
||||
|
||||
def comment_email_subject
|
||||
I18n.t('notifier.a_post_you_shared')
|
||||
end
|
||||
|
||||
# @return [Array<Comment>]
|
||||
def last_three_comments
|
||||
self.comments.order('created_at DESC').limit(3).includes(:author => :profile).reverse
|
||||
|
|
|
|||
|
|
@ -20,17 +20,14 @@ class Reshare < Post
|
|||
def receive(recipient, sender)
|
||||
local_reshare = Reshare.where(:guid => self.guid).first
|
||||
if local_reshare && local_reshare.root.author_id == recipient.person.id
|
||||
local_reshare.root.reshares << local_reshare
|
||||
|
||||
if recipient.contact_for(sender)
|
||||
local_reshare.receive(recipient, sender)
|
||||
end
|
||||
|
||||
else
|
||||
super(recipient, sender)
|
||||
return unless recipient.has_contact_for?(sender)
|
||||
end
|
||||
super(recipient, sender)
|
||||
end
|
||||
|
||||
def comment_email_subject
|
||||
I18n.t('reshares.comment_email_subject', :resharer => author.name, :author => root.author.name)
|
||||
end
|
||||
private
|
||||
|
||||
def after_parse
|
||||
|
|
|
|||
|
|
@ -18,6 +18,14 @@ class ServiceUser < ActiveRecord::Base
|
|||
self.person_id.present?
|
||||
end
|
||||
|
||||
def self.username_of_service_user_by_uid(uid)
|
||||
if su = ServiceUser.find_by_uid(uid)
|
||||
su.username
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def attach_local_models
|
||||
service_for_uid = Services::Facebook.where(:type => service.type.to_s, :uid => self.uid).first
|
||||
if !service_for_uid.blank? && (service_for_uid.user.person.profile.searchable)
|
||||
|
|
@ -30,8 +38,8 @@ class ServiceUser < ActiveRecord::Base
|
|||
self.contact = self.service.user.contact_for(self.person)
|
||||
end
|
||||
|
||||
self.invitation = Invitation.joins(:recipient).where(:sender_id => self.service.user_id,
|
||||
:users => {:invitation_service => self.service.provider,
|
||||
:invitation_identifier => self.uid}).first
|
||||
self.invitation = Invitation.where(:sender_id => self.service.user_id,
|
||||
:service => self.service.provider,
|
||||
:identifier => self.uid).first
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Services::Facebook < Service
|
|||
else
|
||||
self.service_users
|
||||
end
|
||||
result.order('service_users.person_id DESC, service_users.name')
|
||||
result.includes(:contact => :aspects, :person => :profile).order('service_users.person_id DESC, service_users.name')
|
||||
end
|
||||
|
||||
def save_friends
|
||||
|
|
@ -38,15 +38,35 @@ class Services::Facebook < Service
|
|||
data = JSON.parse(response.body)['data']
|
||||
return unless data
|
||||
data.map!{ |p|
|
||||
su = ServiceUser.new(:service_id => self.id, :uid => p["id"], :photo_url => p["picture"], :name => p["name"])
|
||||
su = ServiceUser.new(:service_id => self.id, :uid => p["id"], :photo_url => p["picture"], :name => p["name"], :username => p["username"])
|
||||
su.attach_local_models
|
||||
su
|
||||
}
|
||||
ServiceUser.import(data, :on_duplicate_key_update => [:updated_at, :contact_id, :person_id, :request_id, :invitation_id, :photo_url, :name])
|
||||
|
||||
|
||||
if postgres?
|
||||
# Take the naive approach to inserting our new visibilities for now.
|
||||
data.each do |su|
|
||||
if existing = ServiceUser.find_by_uid(su.uid)
|
||||
update_hash = OVERRIDE_FIELDS_ON_FB_UPDATE.inject({}) do |acc, element|
|
||||
acc[element] = su.send(element)
|
||||
acc
|
||||
end
|
||||
|
||||
existing.update_attributes(update_hash)
|
||||
else
|
||||
su.save
|
||||
end
|
||||
end
|
||||
else
|
||||
ServiceUser.import(data, :on_duplicate_key_update => OVERRIDE_FIELDS_ON_FB_UPDATE + [:updated_at])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
OVERRIDE_FIELDS_ON_FB_UPDATE = [:contact_id, :person_id, :request_id, :invitation_id, :photo_url, :name, :username]
|
||||
|
||||
def prevent_service_users_from_being_empty
|
||||
if self.service_users.blank?
|
||||
self.save_friends
|
||||
|
|
|
|||
|
|
@ -132,6 +132,10 @@ class StatusMessage < Post
|
|||
end
|
||||
end
|
||||
|
||||
def comment_email_subject
|
||||
formatted_message(:plain_text => true)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def message_or_photos_present?
|
||||
|
|
|
|||
|
|
@ -46,12 +46,58 @@ class User < ActiveRecord::Base
|
|||
has_many :authorizations, :class_name => 'OAuth2::Provider::Models::ActiveRecord::Authorization', :foreign_key => :resource_owner_id
|
||||
has_many :applications, :through => :authorizations, :source => :client
|
||||
|
||||
before_save do
|
||||
person.save if person && person.changed?
|
||||
end
|
||||
before_save :guard_unconfirmed_email
|
||||
before_save :guard_unconfirmed_email,
|
||||
:save_person!
|
||||
|
||||
before_create :infer_email_from_invitation_provider
|
||||
|
||||
attr_accessible :getting_started,
|
||||
:password,
|
||||
:password_confirmation,
|
||||
:language,
|
||||
:disable_mail,
|
||||
:invitation_service,
|
||||
:invitation_identifier
|
||||
|
||||
|
||||
# @return [User]
|
||||
def self.find_by_invitation(invitation)
|
||||
service = invitation.service
|
||||
identifier = invitation.identifier
|
||||
|
||||
if service == 'email'
|
||||
existing_user = User.where(:email => identifier).first
|
||||
else
|
||||
existing_user = User.joins(:services).where(:services => {:type => "Services::#{service.titleize}", :uid => identifier}).first
|
||||
end
|
||||
|
||||
if existing_user.nil?
|
||||
i = Invitation.where(:service => service, :identifier => identifier).first
|
||||
existing_user = i.recipient if i
|
||||
end
|
||||
|
||||
existing_user
|
||||
end
|
||||
|
||||
# @return [User]
|
||||
def self.find_or_create_by_invitation(invitation)
|
||||
if existing_user = self.find_by_invitation(invitation)
|
||||
existing_user
|
||||
else
|
||||
self.create_from_invitation!(invitation)
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_from_invitation!(invitation)
|
||||
user = User.new
|
||||
user.generate_keys
|
||||
user.send(:generate_invitation_token)
|
||||
user.email = invitation.identifier if invitation.service == 'email'
|
||||
# we need to make a custom validator here to make this safer
|
||||
user.save(:validate => false)
|
||||
user
|
||||
end
|
||||
|
||||
attr_accessible :getting_started, :password, :password_confirmation, :language, :disable_mail
|
||||
|
||||
def update_user_preferences(pref_hash)
|
||||
if self.disable_mail
|
||||
|
|
@ -267,20 +313,6 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
###Invitations############
|
||||
def invite_user(aspect_id, service, identifier, invite_message = "")
|
||||
aspect = aspects.find(aspect_id)
|
||||
if aspect
|
||||
Invitation.invite(:service => service,
|
||||
:identifier => identifier,
|
||||
:from => self,
|
||||
:into => aspect,
|
||||
:message => invite_message)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# This method is called when an invited user accepts his invitation
|
||||
#
|
||||
# @param [Hash] opts the options to accept the invitation with
|
||||
|
|
@ -289,25 +321,29 @@ class User < ActiveRecord::Base
|
|||
# @option opts [String] :password_confirmation
|
||||
def accept_invitation!(opts = {})
|
||||
log_hash = {:event => :invitation_accepted, :username => opts[:username], :uid => self.id}
|
||||
log_hash[:inviter] = invitations_to_me.first.sender.diaspora_handle if invitations_to_me.first
|
||||
begin
|
||||
if self.invited?
|
||||
self.setup(opts)
|
||||
self.invitation_token = nil
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
self.save!
|
||||
invitations_to_me.each{|invitation| invitation.share_with!}
|
||||
log_hash[:status] = "success"
|
||||
Rails.logger.info log_hash
|
||||
log_hash[:inviter] = invitations_to_me.first.sender.diaspora_handle if invitations_to_me.first && invitations_to_me.first.sender
|
||||
|
||||
self.reload # Because to_request adds a request and saves elsewhere
|
||||
self
|
||||
if self.invited?
|
||||
self.setup(opts)
|
||||
self.invitation_token = nil
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
|
||||
self.save
|
||||
return unless self.errors.empty?
|
||||
|
||||
# moved old Invitation#share_with! logic into here,
|
||||
# but i don't think we want to destroy the invitation
|
||||
# anymore. we may want to just call self.share_with
|
||||
invitations_to_me.each do |invitation|
|
||||
if !invitation.admin? && invitation.sender.share_with(self.person, invitation.aspect)
|
||||
invitation.destroy
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
log_hash[:status] = "failure"
|
||||
Rails.logger.info log_hash
|
||||
raise e
|
||||
|
||||
log_hash[:status] = "success"
|
||||
Rails.logger.info(log_hash)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -321,43 +357,35 @@ class User < ActiveRecord::Base
|
|||
def setup(opts)
|
||||
self.username = opts[:username]
|
||||
self.email = opts[:email]
|
||||
self.language ||= 'en'
|
||||
self.valid?
|
||||
errors = self.errors
|
||||
errors.delete :person
|
||||
return if errors.size > 0
|
||||
|
||||
opts[:person] ||= {}
|
||||
unless opts[:person][:profile].is_a?(Profile)
|
||||
opts[:person][:profile] ||= Profile.new
|
||||
opts[:person][:profile] = Profile.new(opts[:person][:profile])
|
||||
end
|
||||
|
||||
self.person = Person.new(opts[:person])
|
||||
self.person.diaspora_handle = "#{opts[:username]}@#{AppConfig[:pod_uri].authority}"
|
||||
self.person.url = AppConfig[:pod_url]
|
||||
|
||||
|
||||
self.serialized_private_key = User.generate_key if self.serialized_private_key.blank?
|
||||
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
|
||||
|
||||
self.set_person(Person.new(opts[:person] || {} ))
|
||||
self.generate_keys
|
||||
self
|
||||
end
|
||||
|
||||
def set_person(person)
|
||||
person.url = AppConfig[:pod_url]
|
||||
person.diaspora_handle = "#{self.username}@#{AppConfig[:pod_uri].authority}"
|
||||
self.person = person
|
||||
end
|
||||
|
||||
def seed_aspects
|
||||
self.aspects.create(:name => I18n.t('aspects.seed.family'))
|
||||
self.aspects.create(:name => I18n.t('aspects.seed.friends'))
|
||||
self.aspects.create(:name => I18n.t('aspects.seed.work'))
|
||||
aq = self.aspects.create(:name => I18n.t('aspects.seed.acquaintances'))
|
||||
|
||||
default_account = Webfinger.new('diasporahq@joindiaspora.com').fetch
|
||||
self.share_with(default_account, aq) if default_account
|
||||
unless AppConfig[:no_follow_diasporahq]
|
||||
default_account = Webfinger.new('diasporahq@joindiaspora.com').fetch
|
||||
self.share_with(default_account, aq) if default_account
|
||||
end
|
||||
aq
|
||||
end
|
||||
|
||||
def self.generate_key
|
||||
key_size = (Rails.env == 'test' ? 512 : 4096)
|
||||
OpenSSL::PKey::RSA::generate(key_size)
|
||||
end
|
||||
|
||||
def encryption_key
|
||||
OpenSSL::PKey::RSA.new(serialized_private_key)
|
||||
|
|
@ -408,4 +436,34 @@ class User < ActiveRecord::Base
|
|||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Generate public/private keys for User and associated Person
|
||||
def generate_keys
|
||||
key_size = (Rails.env == 'test' ? 512 : 4096)
|
||||
|
||||
self.serialized_private_key = OpenSSL::PKey::RSA::generate(key_size) if self.serialized_private_key.blank?
|
||||
|
||||
if self.person && self.person.serialized_public_key.blank?
|
||||
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
|
||||
end
|
||||
end
|
||||
|
||||
# Sometimes we access the person in a strange way and need to do this
|
||||
# @note we should make this method depricated.
|
||||
#
|
||||
# @return [Person]
|
||||
def save_person!
|
||||
self.person.save if self.person && self.person.changed?
|
||||
self.person
|
||||
end
|
||||
|
||||
# Set the User's email to the one they've been invited at, if the user
|
||||
# is being created via an invitation.
|
||||
#
|
||||
# @return [User]
|
||||
def infer_email_from_invitation_provider
|
||||
self.email = self.invitation_identifier if self.invitation_service == 'email'
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,109 @@
|
|||
|
||||
.span-24.last
|
||||
%br
|
||||
%br
|
||||
%h1
|
||||
Usage Statistics
|
||||
%div{:style => "float:right;"}
|
||||
= form_tag('/admins/stats', :method => 'get') do
|
||||
%select{:name => 'range'}
|
||||
%option{:value => 'daily', :selected => ('selected' if params[:range] == 'daily')}
|
||||
Daily
|
||||
%option{:value => 'week', :selected => ('selected' if params[:range] == 'week')}
|
||||
Week
|
||||
%option{:value => '2weeks', :selected => ('selected' if params[:range] == '2weeks')}
|
||||
2 Weeks
|
||||
%option{:value => 'month', :selected => ('selected' if params[:range] == 'month')}
|
||||
Month
|
||||
|
||||
= submit_tag 'go'
|
||||
%br
|
||||
%h3
|
||||
Displaying results from the
|
||||
%b
|
||||
= @segment
|
||||
segment
|
||||
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
|
||||
%hr
|
||||
.clearfix
|
||||
|
||||
.span-24.last
|
||||
- [:posts, :comments, :aspect_memberships, :users].each do |name|
|
||||
- model = eval("@#{name.to_s}")
|
||||
- if name == :aspect_memberships
|
||||
- name = :shares
|
||||
|
||||
.span-6{:class => ('last' if name == :users)}
|
||||
%h2{:style => 'font-weight:bold;'}
|
||||
= model[:yesterday]
|
||||
= name.to_s
|
||||
%h4
|
||||
= model[:day_before]
|
||||
%span.percent_change{:class => (model[:change] > 0 ? "green" : "red")}
|
||||
= "(#{model[:change]}%)"
|
||||
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%hr
|
||||
|
||||
|
||||
%p{:style => "text-align:center;"}
|
||||
The current segment is averaging
|
||||
%b
|
||||
#{@posts[:yesterday]/@user_count.to_f}
|
||||
posts per user, from
|
||||
%b
|
||||
#{@posts[:day_before]/@user_count.to_f}
|
||||
|
||||
/%h3
|
||||
/ Posts over time
|
||||
|
||||
/#stats_graph{:style => "text-align:right;position:relative;vertical-align:bottom;background-color:#eee;"}
|
||||
/ = @posts_per_day.inspect
|
||||
/ /- @posts_per_day.each do |key, val|
|
||||
/ / .asdo{:style => "display:inline-block;width:35px;vertical-align:bottom;background-color:#666;height:#{(val/@most_posts_within)*200}px;"}
|
||||
|
||||
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
|
||||
|
||||
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
|
||||
.span-24.last
|
||||
%h2
|
||||
Misc Stuff
|
||||
%br
|
||||
%br
|
||||
|
||||
%h3
|
||||
= for tg in @popular_tags
|
||||
= link_to tg, tags_path(tg)
|
||||
|
|
@ -9,8 +114,8 @@
|
|||
.span-12
|
||||
%h3
|
||||
New public posts
|
||||
.stream
|
||||
= render 'shared/stream', :posts => @new_posts
|
||||
/.stream
|
||||
/ /= render 'shared/stream', :posts => @new_public_posts
|
||||
|
||||
.span-12.last
|
||||
%h3
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
= user.person.profile.inspect
|
||||
%br
|
||||
= "invite token: #{accept_invitation_url(user, :invitation_token => user.invitation_token)}" if user.invitation_token
|
||||
= link_to "add 10 invites for this user", add_invites_path(:user_id => user.id)
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
-# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
.dropdown{:class => "hang_#{hang}"}
|
||||
.button.toggle{:class => ("in_aspects" if contact.aspects.size > 0)}
|
||||
- if contact.aspects.size == 1
|
||||
= contact.aspects.first.name
|
||||
- else
|
||||
= t('.toggle', :count => contact.aspects.size)
|
||||
▼
|
||||
|
||||
.wrapper
|
||||
%ul.dropdown_list{:unSelectable => 'on', 'data-person_id' => ((person.id) if person)}
|
||||
- for aspect in all_aspects
|
||||
= aspect_dropdown_list_item(aspect, contact, person)
|
||||
|
||||
- if defined?(@aspect) && ( @aspect == :profile || @aspect == :getting_started || @aspect == :tag || @aspect == :search || @aspect == :notification)
|
||||
%li.newItem
|
||||
.add_aspect
|
||||
= link_to t('contacts.index.add_a_new_aspect'), new_aspect_path(:person_id => person.id), :rel => 'facebox', :class => 'new_aspect'
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
-# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
= aspect_dropdown_list_item(aspect, contact, person)
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
-# the COPYRIGHT file.
|
||||
|
||||
%ul#aspect_nav.left_nav
|
||||
%li.all_aspects{:class => ("active" if params["set"] != "all" && params["set"] != "only_sharing" && !defined?(@featured))}
|
||||
%li.all_aspects{:class => ("active" if params["set"] != "all" && params["set"] != "only_sharing" && !@featured && !@finder)}
|
||||
%a.home_selector{:href => controller_index_path, :class => ("sub_selected" if params["a_id"])}
|
||||
.contact_count
|
||||
= my_contacts_count
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
- for aspect in all_aspects
|
||||
%li{:data => {:aspect_id => aspect.id}, :class => ("active" if params["a_id"].to_i == aspect.id)}
|
||||
.edit
|
||||
= link_to image_tag("icons/pencil.svg", :height => 12), edit_aspect_path(aspect), :rel => "facebox"
|
||||
= link_to image_tag("icons/pencil.svg", :height => 12, :title => t('contacts.index.edit_aspect', :name => aspect.name)), edit_aspect_path(aspect), :rel => "facebox"
|
||||
|
||||
%a.aspect_selector{aspect_listing_link_opts(aspect)}
|
||||
.contact_count
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
- else
|
||||
= @aspects.to_sentence
|
||||
|
||||
= render 'shared/publisher', :aspect => aspect, :aspect_ids => aspect_ids
|
||||
= render 'shared/publisher', :selected_aspects => @aspects, :aspect_ids => aspect_ids, :aspect => @aspect
|
||||
|
||||
- if posts.length == 0
|
||||
= render 'aspects/no_posts_message'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// the COPYRIGHT file.
|
||||
|
||||
var dropdown = $("ul.dropdown_list[data-person_id=<%= @person.id %>]")
|
||||
$('.newItem', dropdown).before("<%= escape_javascript( render('aspect_memberships/aspect_dropdown_list_item', :aspect => @aspect, :person => @person, :contact => @contact)) %>");
|
||||
$('.newItem', dropdown).before("<%= escape_javascript( aspect_dropdown_list_item(@aspect, @contact.aspects.include?(@aspect))) %>");
|
||||
|
||||
ContactEdit.updateNumber(dropdown, "<%= @person.id %>", <%= @contact.aspects.size %>);
|
||||
$.facebox.close();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
$('#aspect_stream_container').html("<%= escape_javascript(render('aspects/aspect_stream', :aspect => @aspect, :aspect_ids => @aspect_ids, :posts => @posts)) %>");
|
||||
$('#selected_aspect_contacts').html("<%= escape_javascript(render('aspects/selected_contacts', :people => @selected_people[0..19], :count => @selected_people.size )) %>");
|
||||
$('#selected_aspect_contacts').html("<%= escape_javascript(render('aspects/selected_contacts', :people => @selected_people.sample(20), :count => @contact_count )) %>");
|
||||
$('#aspect_stream_container a[rel*=facebox]').facebox();
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@
|
|||
%a.more-link.paginate{:href => next_page_path}
|
||||
%h2= t("more")
|
||||
- content_for :subpages do
|
||||
= render 'shared/publisher', :aspect_ids => @aspect_ids
|
||||
= render 'shared/publisher', :aspect_ids => @aspect_ids, :selected_aspects => @aspects, :aspect => @aspect
|
||||
|
|
|
|||
24
app/views/authorizations/index.mobile.haml
Normal file
24
app/views/authorizations/index.mobile.haml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
%h3
|
||||
= t('_applications')
|
||||
#applications_stream.stream
|
||||
- if @applications.count > 0
|
||||
- for app in @applications
|
||||
.stream_element{:id => app.id}
|
||||
.right
|
||||
= link_to t('.revoke_access'), authorization_path(:id => app.id), :method => :delete, :confirm => 'are you sure?', :class => "button"
|
||||
|
||||
- if app.icon_url
|
||||
= image_tag(app.application_base_url + app.icon_url, :class => "avatar")
|
||||
|
||||
.content
|
||||
%div.from
|
||||
= link_to app.name, app.application_base_url
|
||||
= app.description
|
||||
|
||||
- else
|
||||
You haven't registered any applications yet.
|
||||
%br
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
= contact.person.diaspora_handle
|
||||
|
||||
.right
|
||||
= render 'aspect_memberships/aspect_dropdown', :contact => contact, :person => contact.person, :hang => 'right'
|
||||
= aspect_membership_dropdown(contact, contact.person, 'right')
|
||||
|
||||
%br
|
||||
%div{:style => "text-align:right;"}
|
||||
|
|
|
|||
|
|
@ -29,4 +29,4 @@
|
|||
= form_for [conversation, Message.new] do |message|
|
||||
= message.text_area :text, :rows => 5, :tabindex => 1
|
||||
.right
|
||||
= message.submit t('.reply').capitalize, :class => 'button creation', :tabindex => 2
|
||||
= message.submit t('.reply').capitalize, :disable_with => t('.replying'), :class => 'button creation', :tabindex => 2
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@ $('#conversation_show').html("<%= escape_javascript(render('conversations/show',
|
|||
|
||||
$(".stream_element", "#conversation_inbox").removeClass('selected');
|
||||
$(".stream_element[data-guid='<%= @conversation.id %>']", "#conversation_inbox").addClass('selected');
|
||||
$(".stream_element[data-guid='<%= @conversation.id %>']", "#conversation_inbox").find(".unread_message_count").remove()
|
||||
|
||||
Diaspora.Page.timeAgo.updateTimeAgo();
|
||||
|
|
|
|||
18
app/views/devise/mailer/_inviter.erb
Normal file
18
app/views/devise/mailer/_inviter.erb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<table style="padding: 20px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody><tr>
|
||||
<td width='100px'></td>
|
||||
<td width="70px">
|
||||
<a href="<%= accept_invitation_url(@resource, :invitation_token => @resource.invitation_token)%>" target="_blank"><img style="border: 0pt none ; padding: 0pt 5px; display: block;" src="<%=invite.sender.person.profile.image_url(:thumb_medium) %>" height="75" ></a>
|
||||
</td>
|
||||
<td style="line-height: 20px; width: 360px;">
|
||||
<%= t('.has_invited_you', :name => invite.sender.name + " (#{invite.sender.diaspora_handle})") %> <br/>
|
||||
|
||||
<% unless invite.message.blank? %>
|
||||
<strong> "<%= invite.message %>"</strong>
|
||||
<% end %>
|
||||
|
||||
</td>
|
||||
<td width='100px'></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
%p
|
||||
- if @invs.count == 1
|
||||
= t('.has_invited_you', :name => @invs.first.sender.name + " (#{@invs.first.sender.diaspora_handle})")
|
||||
- else
|
||||
= t('.have_invited_you', :names => (@invs.map{|inv| inv.sender.name + " (#{inv.sender.diaspora_handle})"}.join(",")))
|
||||
= t('.accept_at', :url => root_url)
|
||||
- @invs.each do |inv|
|
||||
- unless inv.message.blank?
|
||||
= "#{inv.sender.name}:"
|
||||
= "\"#{inv.message}\""
|
||||
%p
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
<% @invites = @resource.invitations_to_me.includes(:sender =>{:person => :profile}).where(:admin => false).all%>
|
||||
<head>
|
||||
<title><%=invite_email_title %></title>
|
||||
</head>
|
||||
<p style="background-color: rgb(255, 255, 255); text-align: center; font-size: 11px;">Email not displaying correctly? <a href="<%=invite_email_url(:invitation_token => @resource.invitation_token) %>" style="color: #3F8FBA; text-decoration: none;">View it</a> in your browser</p>
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td style="padding: 30px 15px 0pt; background-color: rgb(221, 221, 221);">
|
||||
|
|
@ -10,14 +14,20 @@
|
|||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td style="padding: 10px 0pt 0px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
Finally - it's here.<br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td style="padding: 0px 20px 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="600" height='389'>
|
||||
<a href="<%= accept_invitation_url(@resource, :invitation_token => @resource.invitation_token)%>" target="_blank"><img src="http://dl.dropbox.com/u/15865/diaspora_shots.jpg" style="border: 0pt none ; display: block;" width="560">
|
||||
</a></td></tr>
|
||||
|
||||
|
||||
<tr><td style="padding: 0pt 30px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; line-height: 20px;">
|
||||
The social network you have been waiting for has arrived. Revamped, more secure, and more fun, <strong>DIASPORA*</strong> is ready to help you share and explore the web in a whole new way.
|
||||
<br>
|
||||
|
|
@ -25,6 +35,46 @@
|
|||
<a style="color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;" href="<%= accept_invitation_url(@resource, :invitation_token => @resource.invitation_token)%>" target="_blank">Sign up now →</a>
|
||||
</td></tr>
|
||||
|
||||
|
||||
<% unless @invites.blank? %>
|
||||
<% @invites_with_message, @invites_without_message = @invites.partition{|x| !x.message.blank?} %>
|
||||
<% unless @invites_with_message.empty? %>
|
||||
<tr>
|
||||
<td style="padding: 10px 0pt 0px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 24px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
<br>
|
||||
What your friends are saying...<br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<% @invites_with_message.each do |i| %>
|
||||
<tr><td>
|
||||
<%= render(:partial => 'devise/mailer/inviter', :locals => {:invite => i}) %>
|
||||
</td></tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% unless @invites_without_message.empty? %>
|
||||
|
||||
<tr>
|
||||
<td style="padding: 10px 0pt 0px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 24px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
<br>
|
||||
Even more people are excited to see you!<br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<% @invites_without_message.each do |i| %>
|
||||
<tr><td>
|
||||
<%= render(:partial => 'devise/mailer/inviter', :locals => {:invite => i}) %>
|
||||
</td></tr>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<tr><td style="padding: 20px 20px 0px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
1. Get Connected</td></tr>
|
||||
<tr><td>
|
||||
|
|
@ -123,4 +173,3 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
- @invs = @resource.invitations_to_me
|
||||
-if @invs.count > 0
|
||||
!!!
|
||||
%html
|
||||
%head
|
||||
%meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/
|
||||
= render :partial => 'notifier/notifier_css'
|
||||
%body
|
||||
%header
|
||||
= image_tag AppConfig[:pod_url] + 'images/logo_caps.png'
|
||||
#container
|
||||
%p
|
||||
= t('devise.mailer.welcome', :email => @resource.email)
|
||||
= render :partial => 'inviters'
|
||||
|
||||
%p= link_to t('.accept'), accept_invitation_url(@resource, :invitation_token => @resource.invitation_token), :class => "large_text"
|
||||
%p.small
|
||||
= t('.ignore')
|
||||
%br/
|
||||
= t('.no_account_till')
|
||||
-else
|
||||
= render :partial => 'devise/mailer/batch_invites'
|
||||
28
app/views/invitations/new.mobile.haml
Normal file
28
app/views/invitations/new.mobile.haml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
:javascript
|
||||
$(function() {
|
||||
$("#user_email").focus();
|
||||
});
|
||||
|
||||
%h2
|
||||
= t('.invite_someone_to_join')
|
||||
|
||||
#email_invitation
|
||||
= form_for User.new, :url => invitation_path(User) do |invite|
|
||||
%h4
|
||||
= t('email')
|
||||
= invite.text_field :email, :title => t('.comma_seperated_plz')
|
||||
%br
|
||||
|
||||
%h4
|
||||
= t('.aspect')
|
||||
= invite.select(:aspects, options_from_collection_for_select(all_aspects, 'id', 'name'))
|
||||
|
||||
%br
|
||||
%br
|
||||
|
||||
%h4
|
||||
= t('.personal_message')
|
||||
= invite.text_area :invite_messages, :rows => 3, :value => ""
|
||||
|
||||
%p
|
||||
= invite.submit t('.send_an_invitation')
|
||||
|
|
@ -51,6 +51,12 @@
|
|||
|
||||
= yield(:head)
|
||||
|
||||
-unless Rails.env == "production"
|
||||
:css
|
||||
.translation_missing {
|
||||
color: purple;
|
||||
background-color: red;
|
||||
}
|
||||
-if AppConfig[:google_a_site]
|
||||
:javascript
|
||||
var _gaq = _gaq || [];
|
||||
|
|
@ -105,8 +111,6 @@
|
|||
%li= link_to t('.whats_new'), 'https://github.com/diaspora/diaspora/wiki/Changelog'
|
||||
%li= link_to(t('layouts.application.toggle'), toggle_mobile_path) if is_mobile_device?
|
||||
= image_tag 'powered_by_diaspora.png', :height => "11px", :width => "145px"
|
||||
%br
|
||||
= link_to t('.have_a_problem'), 'http://diaspora.shapado.com/'
|
||||
|
||||
-if !@landing_page && request.url.match(/joindiaspora.com/)
|
||||
:javascript
|
||||
|
|
|
|||
|
|
@ -85,7 +85,16 @@
|
|||
= link_to t('conversations.index.message_inbox'), conversations_path
|
||||
.ui-li-count
|
||||
= @unread_message_count
|
||||
|
||||
|
||||
|
||||
|
||||
- if AppConfig[:open_invitations]
|
||||
%h4
|
||||
= t('shared.invitations.invite_your_friends')
|
||||
%ul{:data => {:role => 'listview', :inset => 'true'}}
|
||||
%li
|
||||
= link_to t('.by_email'), new_user_invitation_path
|
||||
|
||||
%h4
|
||||
= t('.your_aspects')
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
.stream_element{:data=>{:guid => note.id}, :class => "#{note.unread ? 'unread' : ''}"}
|
||||
- if note.type == "Notifications::StartedSharing" && contact = current_user.contact_for(note[:target])
|
||||
.right
|
||||
= render 'aspect_memberships/aspect_dropdown', :contact => contact, :person => note[:target], :hang => 'left'
|
||||
= aspect_membership_dropdown(contact, note[:target], 'left')
|
||||
|
||||
%span.from
|
||||
= notification_message_for(note)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%p
|
||||
= post_message(@comment, :process_newlines => true, :length => 600)
|
||||
= comment_message(@comment.text, :process_newlines => true)
|
||||
%p
|
||||
= link_to t('notifier.comment_on_post.reply', :name => @comment.post.author.first_name), post_url(@comment.post)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!= truncate(@comment.text, :length => 600)
|
||||
!= comment_message(@comment.text)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%p
|
||||
= post_message(@comment, :process_newlines => true, :length => 600)
|
||||
= comment_message(@comment.text, :process_newlines => true)
|
||||
%p
|
||||
= link_to t('notifier.comment_on_post.reply', :name => @comment.post.author.name), post_url(@comment.post)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!= truncate(@comment.text, :length => 600)
|
||||
!= comment_message(@comment.text)
|
||||
|
|
|
|||
1
app/views/people/_aspect_membership_dropdown.haml
Normal file
1
app/views/people/_aspect_membership_dropdown.haml
Normal file
|
|
@ -0,0 +1 @@
|
|||
= aspect_membership_dropdown(@contact, @person, 'left')
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
- unless person == current_user.person
|
||||
- contact = current_user.contacts.find_by_person_id(person.id)
|
||||
- contact ||= Contact.new(:person => person)
|
||||
= render 'aspect_memberships/aspect_dropdown', :contact => contact, :person => person, :hang => 'left'
|
||||
= aspect_membership_dropdown(contact, person, 'left')
|
||||
-else
|
||||
= t('people.person.thats_you')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#author_info
|
||||
.right
|
||||
- if user_signed_in? && current_user.person != person
|
||||
= render 'aspect_memberships/aspect_dropdown', :contact => contact, :person => person, :hang => 'left'
|
||||
= aspect_membership_dropdown(contact, person, 'left')
|
||||
- elsif user_signed_in? && current_user.person == person
|
||||
= link_to t('people.profile_sidebar.edit_my_profile'), edit_profile_path, :class => 'button creation'
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@
|
|||
= t('ago', :time => time_ago_in_words(@post.created_at))
|
||||
|
||||
%br
|
||||
- if current_user.owns? @post
|
||||
= link_to t('delete'), post_path(@post), :confirm => t('are_you_sure'), :method => :delete
|
||||
- else
|
||||
= link_to t('hide'), post_visibility_path(:id => "42", :post_id => @post.id), :confirm => t('are_you_sure'), :method => :put, :remote => true
|
||||
- if user_signed_in?
|
||||
- if current_user.owns? @post
|
||||
= link_to t('delete'), post_path(@post), :confirm => t('are_you_sure'), :method => :delete
|
||||
- else
|
||||
= link_to t('hide'), post_visibility_path(:id => "42", :post_id => @post.id), :confirm => t('are_you_sure'), :method => :put, :remote => true
|
||||
|
||||
.stream.show{:data=>{:guid=>@post.id}}
|
||||
= render "comments/comments", :post => @post, :comments => @post.comments, :comments_expanded => true
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
= form_tag service_inviter_path(:provider => 'facebook') do
|
||||
= select_tag(:aspect_id, options_from_collection_for_select(all_aspects, 'id', 'name'))
|
||||
= hidden_field_tag :uid, uid
|
||||
= submit_tag t('services.remote_friend.invite')
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
-# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
= search_field_tag :contact_search, "", :class => 'contact_list_search', :results => 5, :placeholder => t('shared.contact_list.all_contacts')
|
||||
|
||||
%ul.friend_finder
|
||||
= render :partial => 'services/remote_friend', :collection => friends, :as => :friend
|
||||
|
|
@ -1,20 +1,28 @@
|
|||
%li.remote_friend{:id => "uid_" + friend.uid, :uid => friend.uid}
|
||||
.stream_element.contact{:id => friend.id}
|
||||
.right
|
||||
|
||||
- if friend.already_invited?
|
||||
= link_to t('.resend'), service_inviter_path(:uid => friend.uid, :provider => 'facebook', :invitation_id => friend.invitation_id), :class => 'button resend'
|
||||
- elsif friend.on_diaspora?
|
||||
= render 'shared/aspect_dropdown', :selected_aspects => contact_proxy(friend).aspects, :person => friend.person, :hang => 'left'
|
||||
- else
|
||||
= render 'shared/aspect_dropdown', :selected_aspects => contact_proxy(friend).aspects, :person => friend.person, :hang => 'left', :dropdown_class => 'inviter', :service_uid => friend.uid
|
||||
|
||||
- if friend.on_diaspora?
|
||||
= person_image_link(friend.person, :size => :thumb_small)
|
||||
- else
|
||||
= image_tag(friend.photo_url, :class => 'avatar')
|
||||
|
||||
%h4.name
|
||||
- if friend.on_diaspora?
|
||||
= link_to friend.name, person_path(friend.person)
|
||||
- else
|
||||
= friend.name
|
||||
|
||||
- if friend.already_invited?
|
||||
= link_to t('.resend'), service_inviter_path(:uid => friend.uid, :provider => 'facebook', :invitation_id => friend.invitation_id)
|
||||
- elsif friend.on_diaspora?
|
||||
= render 'aspect_memberships/aspect_dropdown', :contact => contact_proxy(friend), :person => friend.person, :hang => 'left'
|
||||
- else
|
||||
= facebook_invite_form(friend)
|
||||
.content
|
||||
%span.from.name
|
||||
- if friend.on_diaspora?
|
||||
= link_to friend.name, person_path(friend.person)
|
||||
- else
|
||||
= friend.name
|
||||
|
||||
|
||||
.info
|
||||
- if friend.person
|
||||
= friend.person.diaspora_handle
|
||||
- else
|
||||
=t('.not_on_diaspora')
|
||||
|
|
|
|||
|
|
@ -5,27 +5,25 @@
|
|||
- content_for :head do
|
||||
= include_javascripts :finder
|
||||
|
||||
#aspect_edit_pane.larger.friend_finder
|
||||
#facebox_header
|
||||
%h4
|
||||
= t('.invite_your_friends_from', :service => params[:provider].titleize)
|
||||
.description
|
||||
- if @friends.size > 0
|
||||
= t('.friends', :count => @friends.size)
|
||||
- else
|
||||
%i= t('.not_connected')
|
||||
#section_header
|
||||
%h2
|
||||
= t('contacts.index.title')
|
||||
|
||||
= render 'shared/contact_sidebar'
|
||||
|
||||
.contact_list
|
||||
.span-18.last.searchable
|
||||
= search_field_tag :contact_search, "", :id => "contact_list_search", :class => 'contact_list_search', :results => 5, :placeholder => t('search')
|
||||
%h3
|
||||
= t('.service_friends', :service => params[:provider].titleize)
|
||||
#people_stream.stream.contacts
|
||||
- if @friends.size > 0
|
||||
= render :partial => 'services/finder', :locals => {:friends => @friends}
|
||||
= render :partial => 'remote_friend', :collection => @friends, :as => :friend
|
||||
|
||||
/= will_paginate @friends
|
||||
- else
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%h4{:style => 'text-align:center;'}
|
||||
= link_to t('services.index.connect_to_facebook'), "/auth/facebook" if AppConfig[:configured_services].include?('facebook')
|
||||
.no_contacts
|
||||
= link_to(image_tag("social_media_logos/facebook-48x48.png"), "/auth/facebook")
|
||||
%br
|
||||
%br
|
||||
%h4
|
||||
= link_to t('services.index.connect_to_facebook'), '/auth/facebook'
|
||||
|
|
|
|||
21
app/views/shared/_aspect_dropdown.html.haml
Normal file
21
app/views/shared/_aspect_dropdown.html.haml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
-# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
.dropdown{:class => ["hang_#{hang}", defined?(dropdown_class) && dropdown_class]}
|
||||
.button.toggle{:class => ("in_aspects" if selected_aspects.size > 0)}
|
||||
- if selected_aspects.size == 1
|
||||
= selected_aspects.first.name
|
||||
- else
|
||||
= t('.toggle', :count => selected_aspects.size)
|
||||
▼
|
||||
|
||||
.wrapper
|
||||
%ul.dropdown_list{:unSelectable => 'on', 'data-person_id' => (person.id if defined?(person) && person), 'data-service_uid' => (service_uid if defined?(service_uid))}
|
||||
- for aspect in all_aspects
|
||||
= aspect_dropdown_list_item(aspect, selected_aspects.include?(aspect) )
|
||||
|
||||
- if (dropdown_may_create_new_aspect && defined?(person) && person)
|
||||
%li.newItem
|
||||
.add_aspect
|
||||
= link_to t('contacts.index.add_a_new_aspect'), new_aspect_path(:person_id => person.id), :rel => 'facebox'
|
||||
|
|
@ -7,10 +7,10 @@
|
|||
= search_field_tag :contact_search, "", :id => "contact_list_search", :class => 'contact_list_search', :results => 5, :placeholder => t('.all_contacts')
|
||||
= t('contacts', :count =>@aspect_contacts_count)
|
||||
|
||||
.contact_list
|
||||
%ul
|
||||
.contact_list.searchable
|
||||
%ul.contacts
|
||||
- for contact in contacts
|
||||
%li{:data=>{:contact_id=>contact.id}}
|
||||
%li.contact{:data=>{:contact_id=>contact.id}}
|
||||
= person_image_tag contact.person
|
||||
.name
|
||||
= link_to contact.person.name, contact.person
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@
|
|||
|
||||
%ul.left_nav
|
||||
- if AppConfig[:featured_users]
|
||||
%li{:class => ("active" if defined?(@featured))}
|
||||
%li{:class => ("active" if @featured)}
|
||||
= link_to t('contacts.featured.featured_users'), "/featured", :class => "element_selector"
|
||||
/%li
|
||||
/ = link_to "Invite friends", "#", :class => "element_selector"
|
||||
|
||||
%li{:class => ("active" if @finder)}
|
||||
= link_to "Facebook Friends", friend_finder_path('facebook'), :class => "element_selector"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
-if AppConfig[:open_invitations]
|
||||
- if AppConfig.configured_services.include?('facebook')
|
||||
- if defined? remote
|
||||
= link_to t('.from_facebook'), friend_finder_path('facebook', :remote => remote), :rel => 'facebox'
|
||||
-else
|
||||
= link_to t('.from_facebook'), friend_finder_path('facebook'), :rel => 'facebox'
|
||||
%br
|
||||
= link_to t('.by_email'), new_user_invitation_path, :title => t('.invite_someone'), :rel => 'facebox'
|
||||
- else
|
||||
= t('.dont_have_now')
|
||||
- if AppConfig.configured_services.include?('facebook')
|
||||
- if defined? remote
|
||||
= link_to t('.from_facebook'), friend_finder_path('facebook', :remote => remote)
|
||||
-else
|
||||
= link_to t('.from_facebook'), friend_finder_path('facebook')
|
||||
%br
|
||||
= link_to t('.by_email'), new_user_invitation_path, :title => t('.invite_someone'), :rel => 'facebox'
|
||||
|
|
|
|||
|
|
@ -29,12 +29,6 @@
|
|||
= hidden_field_tag 'aspect_ids[]', aspect_id.to_s
|
||||
|
||||
.options_and_submit
|
||||
- if aspect == :profile
|
||||
.mention_helper
|
||||
.badges
|
||||
%i= t('.publishing_to')
|
||||
= aspect_badges(aspects_with_person, :link => false)
|
||||
|
||||
.public_toggle
|
||||
%span#publisher_service_icons
|
||||
= t("shared.publisher.click_to_share_with")
|
||||
|
|
@ -45,6 +39,7 @@
|
|||
- for service in current_user.services
|
||||
= image_tag "social_media_logos/#{service.provider}-16x16.png", :title => service.provider.titleize, :class => "service_icon dim", :id =>"#{service.provider}", :maxchar => "#{service.class::MAX_CHARACTERS}"
|
||||
= link_to (image_tag "icons/monotone_wrench_settings.png"), "#question_mark_pane", :class => 'question_mark', :rel => 'facebox', :title => t('shared.public_explain.manage')
|
||||
= render "shared/aspect_dropdown", :selected_aspects => selected_aspects, :hang => 'left'
|
||||
= status.submit t('.share'), :disable_with => t('.posting'), :class => 'button creation', :tabindex => 2
|
||||
|
||||
.facebox_content
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
-# the COPYRIGHT file.
|
||||
|
||||
|
||||
- unless AppConfig[:invites_off]
|
||||
- if AppConfig[:open_invitations]
|
||||
.section
|
||||
.title
|
||||
= image_tag('/images/icons/plus.png')
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
|
||||
.stream_element{:id => post.guid}
|
||||
- if user_signed_in?
|
||||
- if post.author.owner_id == current_user.id
|
||||
.right.controls
|
||||
= link_to image_tag('deletelabel.png'), post_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete stream_element_delete", :title => t('delete')
|
||||
|
||||
- else
|
||||
.right.controls
|
||||
= link_to image_tag('deletelabel.png'), post_visibility_path(:id => "42", :post_id => post.id), :method => :put, :remote => true, :class => "delete stream_element_delete", :title => t('hide')
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
if ("#{params[:notes]}".length > 0){
|
||||
contents = contents + " - #{params[:notes]}";
|
||||
}
|
||||
|
||||
|
||||
$("#publisher #status_message_fake_text").val(contents);
|
||||
$("#publisher #status_message_text").val(contents);
|
||||
$('input.button')[0].removeAttribute('disabled');
|
||||
|
|
@ -34,5 +34,5 @@
|
|||
.span-15.last
|
||||
%h4
|
||||
=t('bookmarklet.post_something')
|
||||
= render :partial => 'shared/publisher', :locals => { :aspect => :profile, :aspects_with_person => @aspects, :aspect_ids => @aspect_ids}
|
||||
= render :partial => 'shared/publisher', :locals => { :aspect => :profile, :selected_aspects => @aspects, :aspect_ids => @aspect_ids }
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
= javascript_include_tag "publisher.js"
|
||||
|
||||
:javascript
|
||||
$(document).ready(function()
|
||||
$(document).ready(function()
|
||||
{
|
||||
var person = {name: '#{@person.name}', handle: '#{@person.diaspora_handle}' };
|
||||
Publisher.autocompletion.onSelect($("#status_message_fake_text"),person,'#{@person.name}');
|
||||
|
|
@ -21,5 +21,5 @@
|
|||
%h3
|
||||
= t('.mentioning', :person => @person.name)
|
||||
|
||||
= render :partial => 'shared/publisher', :locals => { :aspect => @aspect, :aspect_ids => @aspect_ids, :aspects_with_person => @aspects_with_person, :person => @person}
|
||||
= render :partial => 'shared/publisher', :locals => { :aspect => @aspect, :aspect_ids => @aspect_ids, :selected_aspects => @aspects_with_person, :person => @person}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,19 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
%ul.left_nav
|
||||
%li
|
||||
%div.root_element
|
||||
= t('aspects.index.tags_following')
|
||||
|
||||
%ul.sub_nav
|
||||
- if current_user.followed_tags.size > 0
|
||||
- for tg in current_user.followed_tags
|
||||
%li.unfollow{:id => tg.name}
|
||||
.unfollow_icon.hidden
|
||||
= link_to image_tag("icons/monotone_close_exit_delete.png", :height => 12), tag_tag_followings_path(:name => tg.name, :remote => true), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :id => "unfollow_" + tg.name
|
||||
=link_to "##{tg.name}", tag_path(:name => tg.name), :class => "tag_selector"
|
||||
- else
|
||||
%li
|
||||
= link_to t('aspects.index.no_tags'), tags_path, :class => "new_aspect"
|
||||
- if user_signed_in?
|
||||
%ul.left_nav
|
||||
%li
|
||||
%div.root_element
|
||||
= t('aspects.index.tags_following')
|
||||
|
||||
%ul.sub_nav
|
||||
- if current_user.followed_tags.size > 0
|
||||
- for tg in current_user.followed_tags
|
||||
%li.unfollow{:id => tg.name}
|
||||
.unfollow_icon.hidden
|
||||
= link_to image_tag("icons/monotone_close_exit_delete.png", :height => 16, :title => t('aspects.index.unfollow_tag', :tag => tg.name)), tag_tag_followings_path(:name => tg.name, :remote => true), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :id => "unfollow_" + tg.name
|
||||
=link_to "##{tg.name}", tag_path(:name => tg.name), :class => "tag_selector"
|
||||
- else
|
||||
%li
|
||||
= link_to t('aspects.index.no_tags'), tags_path, :class => "new_aspect"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue