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:
Dan Hansen 2011-08-20 14:40:56 -05:00
commit 3ed50cab94
236 changed files with 3448 additions and 2304 deletions

View file

@ -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'

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
class DiasporaDeviseMailer < Devise::Mailer
include NotifierHelper
default :from => AppConfig[:smtp_sender_address]
end

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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

View 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

View file

@ -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|

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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]]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
&#9660;
.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'

View file

@ -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)

View file

@ -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

View file

@ -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'

View file

@ -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();

View file

@ -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();

View file

@ -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

View 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

View file

@ -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;"}

View file

@ -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

View file

@ -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();

View 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>

View file

@ -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

View file

@ -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 &rarr;</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>

View file

@ -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'

View 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')

View file

@ -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

View file

@ -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')

View file

@ -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)

View file

@ -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)

View file

@ -1 +1 @@
!= truncate(@comment.text, :length => 600)
!= comment_message(@comment.text)

View file

@ -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)

View file

@ -1 +1 @@
!= truncate(@comment.text, :length => 600)
!= comment_message(@comment.text)

View file

@ -0,0 +1 @@
= aspect_membership_dropdown(@contact, @person, 'left')

View file

@ -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')

View file

@ -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'

View file

@ -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

View file

@ -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')

View file

@ -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

View file

@ -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')

View file

@ -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'

View 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)
&#9660;
.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'

View file

@ -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

View file

@ -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"

View file

@ -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'

View file

@ -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

View file

@ -3,7 +3,7 @@
-# the COPYRIGHT file.
- unless AppConfig[:invites_off]
- if AppConfig[:open_invitations]
.section
.title
= image_tag('/images/icons/plus.png')

View file

@ -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')

View file

@ -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 }

View file

@ -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}

View file

@ -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