Permalink
Browse files

Merge branch 'dev' into email-invitation-converted

Conflicts:
	app/controllers/application_controller.rb
	app/views/welcome/_sidebar.html.haml
  • Loading branch information...
2 parents b61de05 + 6ae8832 commit c70b94086874f7c802be26560364b80505b65543 Alex Bredariol Grilo committed Nov 22, 2011
Showing with 638 additions and 235 deletions.
  1. +26 −12 app/controllers/application_controller.rb
  2. +1 −1 app/controllers/auth_callback_controller.rb
  3. +1 −1 app/controllers/searches_controller.rb
  4. +1 −0 app/controllers/signup_wizard_controller.rb
  5. +1 −1 app/controllers/topics_controller.rb
  6. +1 −1 app/controllers/users_controller.rb
  7. +4 −0 app/controllers/welcome_controller.rb
  8. +52 −0 app/helpers/application_helper.rb
  9. +32 −13 app/models/answer.rb
  10. +0 −2 app/models/comment.rb
  11. +1 −3 app/models/news_item.rb
  12. +0 −1 app/models/question.rb
  13. +4 −0 app/models/search_result.rb
  14. +12 −0 app/models/suggestion.rb
  15. +27 −18 app/models/suggestion_list.rb
  16. +2 −6 app/models/topic.rb
  17. +2 −1 app/models/user.rb
  18. +2 −4 app/models/user_suggestion.rb
  19. +2 −5 app/stylesheets/_base.sass
  20. +8 −5 app/stylesheets/application.sass
  21. +1 −1 app/stylesheets/inline_edition.sass
  22. +3 −0 app/stylesheets/themes/plain/_base.sass
  23. +26 −0 app/stylesheets/themes/plain/_questions.sass
  24. +1 −0 app/stylesheets/themes/plain/_search.sass
  25. +24 −0 app/stylesheets/themes/plain/_sidebar.sass
  26. +3 −0 app/stylesheets/themes/plain/_users.sass
  27. +4 −0 app/views/answers/show.html.haml
  28. +0 −14 app/views/comments/_comment.html.haml
  29. +4 −1 app/views/comments/_count.html.haml
  30. +8 −1 app/views/layouts/application.html.haml
  31. +1 −0 app/views/layouts/welcome.html.haml
  32. +43 −27 app/views/questions/_answer_with_form.html.haml
  33. +9 −13 app/views/questions/show.html.haml
  34. +22 −6 app/views/search_results/_form.html.haml
  35. +1 −3 app/views/searches/search_as_new_question.html.haml
  36. +4 −12 app/views/shared/_analytics.haml
  37. +3 −6 app/views/shared/_other_actions.html.haml
  38. +4 −0 app/views/signup_wizard/wizard.html.haml
  39. +1 −6 app/views/topics/_common.html.haml
  40. +4 −0 app/views/topics/show.html.haml
  41. +3 −0 app/views/users/_form_signup.html.haml
  42. +2 −1 app/views/users/_profile_common.html.haml
  43. +5 −10 app/views/users/_signup.html.haml
  44. +42 −1 app/views/welcome/_sidebar.html.haml
  45. +3 −0 app/views/welcome/landing.html.haml
  46. +2 −0 config/assets.yml
  47. +2 −1 config/locales/answers/en.yml
  48. +2 −1 config/locales/answers/pt-BR.yml
  49. +4 −1 config/locales/comments/en.yml
  50. +3 −0 config/locales/comments/pt-BR.yml
  51. +2 −2 config/locales/questions/en.yml
  52. +1 −0 config/locales/search_results/en.yml
  53. +1 −0 config/locales/search_results/pt-BR.yml
  54. +6 −0 config/locales/url_invitations/en.yml
  55. +6 −0 config/locales/url_invitations/pt-BR.yml
  56. +5 −0 config/routes.rb
  57. +0 −5 experiments/answer_with_form_position.rb
  58. +1 −1 experiments/email_converted_invitation.rb
  59. +5 −0 experiments/link_only_answer_form.rb
  60. +1 −1 experiments/new_question_as_search.rb
  61. +1 −1 experiments/news_items_search_results_helpers.rb
  62. +1 −1 experiments/question_responding_helpers.rb
  63. +2 −0 experiments/sign_in_with_facebook.rb
  64. +13 −9 lib/support/bing.rb
  65. +27 −0 lib/support/embedly.rb
  66. +2 −1 lib/support/search.rb
  67. +0 −1 lib/tasks/cron.rake
  68. +0 −16 lib/tasks/data_migrations.rake
  69. +20 −0 lib/tasks/news_items.rake
  70. +7 −9 lib/tasks/suggestions.rake
  71. +87 −0 lib/tasks/topics.rake
  72. BIN public/images/buttons/twitter.png
  73. +1 −1 public/javascripts/autocompleteBox.js
  74. +5 −2 public/javascripts/i18n/en.js
  75. +4 −1 public/javascripts/i18n/pt-BR.js
  76. +3 −3 public/javascripts/modules/inline_edition.js
  77. +18 −0 public/javascripts/modules/mixpanel.js
  78. +6 −2 public/javascripts/modules/show_question.js
@@ -32,7 +32,7 @@ def _vanity_identity
if current_user.tracked?
current_user
else
- set_vanity_cookie(Umamao::UntrackedUser.instance.id)
+ set_identity_cookie(Umamao::UntrackedUser.instance.id)
Umamao::UntrackedUser.instance
end
end
@@ -43,18 +43,18 @@ def _vanity_identity
#
# Options:
# exclude_guests: don't track non-logged visitors _at all_.
- def identify_vanity(options = {})
- if options[:inviter] && (url = UrlInvitation.first(:invitee_ids => current_user.id))
- return url.inviter.id
- end
+ # inviter: track the user's inviter.
+ def identifier(options = {})
+ if (identity = _vanity_identity) && !options[:preserve_identity]
+ if options[:inviter] && (url = UrlInvitation.first(:invitee_ids => identity.id))
+ return url.inviter.id
+ end
- if identity = _vanity_identity
identity.id
elsif options[:exclude_guests]
Umamao::UntrackedUser.instance.id
else
- set_vanity_cookie(SecureRandom.hex(16)) unless cookies[:vanity_id]
- cookies[:vanity_id]
+ obtain_identity_cookie
end
end
@@ -90,6 +90,22 @@ def handle_signup_track(user, url_invitation, group_invitation)
end
+ # If there's a logged user, should track according to User#tracked?,
+ # otherwise should track if the cookie is not that of an untracked user.
+ def should_track?
+ if logged_in?
+ current_user.tracked?
+ else
+ obtain_identity_cookie != Umamao::UntrackedUser.instance.id
+ end
+ end
+ helper_method :should_track?
+
+ def obtain_identity_cookie
+ set_identity_cookie(SecureRandom.hex(16)) unless cookies[:identity]
+ cookies[:identity]
+ end
+
protected
def ensure_domain
@@ -388,9 +404,7 @@ def build_datetime(params, name)
private
- def set_vanity_cookie(value)
- unless cookies[:vanity_id] == value
- cookies[:vanity_id] = { :value => value, :expires => Time.now + 10.years }
- end
+ def set_identity_cookie(value)
+ cookies[:identity] = { :value => value, :expires => Time.now + 2.weeks }
end
end
@@ -4,7 +4,7 @@ class AuthCallbackController < ApplicationController
def callback
auth_hash = request.env['omniauth.auth']
- if not user_signed_in? && auth_hash['provider'] == 'facebook'
+ if !user_signed_in? && auth_hash['provider'] == 'facebook'
signup_with_provider
else
create_external_account
@@ -17,7 +17,7 @@ def index
if @question.parent_question_id
@question.topics = Question.find_by_id(@question.parent_question_id).topics
end
- @bing_results = Support::Bing.search(@question.title)
+ @bing_results = Support::Bing.search(@question.title, :max_results => 10)
end
if params[:q].present?
@@ -8,6 +8,7 @@ def wizard
current_user.save!
redirect_to root_path
else
+ @current_step = params[:current_step]
render :layout => "welcome"
end
end
@@ -79,7 +79,7 @@ def show
def edit
@topic = Topic.find_by_slug_or_id(params[:id])
- unless current_user.can_modify?(@topic)
+ unless current_user.admin?
redirect_to @topic
return
end
@@ -17,7 +17,7 @@ def index
:page => params[:page] || 1}
options[:login] = /^#{Regexp.escape(params[:q])}/ if params[:q]
- @users = current_group.paginate_users(options)
+ @users = User.paginate(options)
respond_to do |format|
format.html
@@ -36,6 +36,10 @@ def home
@questions = Question.latest.limit(10) || [] if @news_items.empty?
@getting_started = Answer.find_by_id("4d42bebf79de4f262d000e4b")
+ if %w[facebook twitter].include?(params[:shared_url_invitation])
+ track_event("shared_invitation_url_via_#{params[:shared_url_invitation]}".to_sym)
+ end
+
set_tab :all, :welcome_home
render 'home'
end
@@ -323,6 +323,8 @@ def shorten_url(url, options = {})
# characters, plus the 3-character '...' divider
options = {:length => 63}.merge(options)
half_length = (options[:length] - 3) / 2
+ scheme, _ = URI.split(url)
+ url = "http://#{url}" unless scheme
uri = URI.parse(url)
port = lambda { |uri| [80, 443].include?(uri.port) ? '' : ":#{uri.port}" }
relevant_path = lambda do |uri|
@@ -379,5 +381,55 @@ def link_to_bing_search(query_string, options = {})
default_options = { :id => :bing_search_link }
link_to_search(:bing, query_string, default_options.merge(options))
end
+
+ def tweet_button(options)
+ link_to('',
+ url_for({ :host => 'twitter.com/share',
+ :original_referer => options[:original_referer],
+ :source => :tweetbutton,
+ :text => options[:text],
+ :url => options[:url] }),
+ :target => :_blank)
+ end
+
+ def facebook_button(options)
+ if options[:action] == :share
+ link_to('Share',
+ nil,
+ :name => 'fb_share',
+ :type => 'button')
+ elsif [:like, :recommend].include?(options[:action])
+ options = { :class => :'fb-like',
+ :'data-action' => options[:action],
+ :'data-href' => options[:url],
+ :'data-layout' => :button_count,
+ :'data-send' => :false,
+ :'data-show-faces' => :false,
+ :'data-width' => '450' }
+ "<div #{options.map { |h| "#{h.first}=\"#{h.last}\"" }.join(' ')}></div>"
+ elsif options[:action] == :feed
+ body = %{<span class="fb_share_size_Small ">
+ <span style="cursor:pointer;" class="FBConnectButton FBConnectButton_Small">
+ <span class="FBConnectButton_Text">Share</span>
+ </span>
+ <span class="fb_share_count_nub_right fb_share_no_count"></span>
+ <span class="fb_share_count fb_share_no_count fb_share_count_right">
+ <span class="fb_share_count_inner">&nbsp;</span>
+ </span>
+ </span>}
+ link_to(raw(body),
+ url_for({ :host => 'www.facebook.com/dialog/feed',
+ :app_id => AppConfig.facebook['app_id'],
+ :caption => options[:caption],
+ :description => options[:description],
+ :link => options[:url],
+ :message => options[:message],
+ :name => options[:name],
+ :picture => 'http://umamao.com/images/default_logo.png',
+ :redirect_uri => options[:redirect_uri] }),
+ :target => :_blank,
+ :style => 'text-decoration: none;')
+ end
+ end
end
View
@@ -42,10 +42,9 @@ class Answer < Comment
versionable_keys :body
filterable_keys :body
- validate :disallow_spam
-
after_create :create_news_update, :new_answer_notification,
:increment_user_topic_answers_count
+ after_update :update_search_result
before_destroy :unhide_news_update, :decrement_user_topic_answers_count
ensure_index([[:user_id, 1], [:question_id, 1]])
@@ -67,8 +66,8 @@ def title(options = {})
end
def summary
- truncate(markdown2txt(body).
- slice((title(:truncated => true).size - 3)..-1).
+ truncate(markdown2txt(body).mb_chars.
+ slice((title(:truncated => true).mb_chars.size - 3)..-1).
to_s.
insert(0, ''),
:length => SearchResult::SUMMARY_SIZE,
@@ -238,6 +237,30 @@ def decrement_user_topic_answers_count
end
def save_with_search_result
+ search_result = new_search_result
+ if save && search_result.save
+ true
+ else
+ search_result.errors.full_messages.each do |error|
+ errors.add_to_base(error)
+ end
+ search_result.destroy
+ false
+ end
+ end
+
+ def update_search_result
+ if !self.search_result
+ create_search_result
+ return
+ end
+
+ self.search_result.set({:title => title(:truncated => true),
+ :summary => summary})
+ end
+
+protected
+ def new_search_result
search_result =
SearchResult.new(:title => title(:truncated => true),
:summary => summary,
@@ -250,14 +273,10 @@ def save_with_search_result
url_helpers.
question_answer_url(question, id))
self.search_result_id = search_result.id
- if save && search_result.save
- true
- else
- search_result.errors.full_messages.each do |error|
- errors.add_to_base(error)
- end
- search_result.destroy
- false
- end
+ search_result
+ end
+
+ def create_search_result
+ new_search_result.save
end
end
View
@@ -25,8 +25,6 @@ class Comment
validates_presence_of :user
- validate :disallow_spam
-
before_save :adjust_newlines
after_create :new_comment_notification,
:unless => :created_together_with_search_result
View
@@ -116,8 +116,6 @@ def show!
# it's not a question that should be hidden
def should_be_hidden?(ignored_topic_ids = [])
entry = self.news_update.entry
-
- !! (entry.is_a?(Question) and entry.answers_count > 0) or
- ( (entry.topic_ids & ignored_topic_ids).any? )
+ (entry.topic_ids & ignored_topic_ids).any?
end
end
View
@@ -136,7 +136,6 @@ class Question
validates_inclusion_of :language, :within => AVAILABLE_LANGUAGES
validates_true_for :language, :logic => lambda { |q| q.group.language == q.language },
:if => lambda { |q| !q.group.language.nil? }
- validate :disallow_spam
validate :check_useful
timestamps!
@@ -228,4 +228,8 @@ def flagged!
{ :$inc => { :flags_count => 1 } },
:upsert => true)
end
+
+ def topic_ids
+ self.question.topic_ids
+ end
end
View
@@ -1,6 +1,8 @@
class Suggestion
include MongoMapper::Document
+ before_destroy :propagate_destruction
+
key :user_id, :required => true, :index => true
belongs_to :user
@@ -17,4 +19,14 @@ class Suggestion
def reject!
self.destroy
end
+
+ def propagate_destruction(options = { :delayed => true })
+ if user
+ if options[:delayed]
+ user.delay.remove_suggestion(self)
+ else
+ user.remove_suggestion(self)
+ end
+ end
+ end
end
@@ -82,25 +82,21 @@ def suggest(thing, options = {})
# suggestion.
def remove_suggestion(suggestion_or_entry)
return if suggestion_or_entry.blank?
- if suggestion_or_entry.is_a?(Suggestion)
- suggestion = suggestion_or_entry
- entry_type = suggestion.entry_type
- else
- entry_id = suggestion_or_entry.id
- entry_type = suggestion_or_entry.class <= Topic ? "Topic" : "User"
- suggestion = Suggestion.first(
- :entry_id => entry_id, :entry_type => entry_type,
- :rejected_at => nil, :accepted_at => nil,
- :origin_id => nil, :user_id => self.user.id)
- end
- return if !suggestion
- if entry_type.constantize < Topic
- self.topic_suggestion_ids.delete(suggestion.id)
- elsif entry_type == "User"
- self.user_suggestion_ids.delete(suggestion.id)
+ suggestion =
+ if suggestion_or_entry.is_a?(Suggestion)
+ suggestion_or_entry
+ else
+ Suggestion.first({ :entry_id => suggestion_or_entry.id,
+ :rejected_at => nil, :accepted_at => nil,
+ :origin_id => nil, :user_id => self.user.id })
+ end
+
+ if suggestion
+ self.remove_from_suggestions!(suggestion.id, suggestion.entry_id)
+ else
+ self.remove_from_suggestions!(suggestion_or_entry.id)
end
- suggestion.reject!
end
# Mark something as uninteresting. Uninteresting users and topics
@@ -124,7 +120,7 @@ def mark_as_uninteresting(thing)
def refuse_suggestion(suggestion)
entry = suggestion.entry
self.mark_as_uninteresting(entry)
- self.remove_suggestion(suggestion)
+ suggestion.reject!
end
# Find suggestions from the user's external accounts.
@@ -214,6 +210,19 @@ def refresh_topic_suggestions
end
end
+ def remove_from_suggestions!(*ids)
+ ids.each do |an_id|
+ user.
+ collection.
+ update({ :_id => user.id },
+ { :$pull =>
+ { 'suggestion_list.user_suggestion_ids' => an_id,
+ 'suggestion_list.topic_suggestion_ids' => an_id,
+ 'suggestion_list.uninteresting_user_ids' => an_id,
+ 'suggestion_list.uninteresting_topic_ids' => an_id } })
+ end
+ end
+
protected
def configured_suggestions
ids = AppConfig.topic_suggestion
Oops, something went wrong.

0 comments on commit c70b940

Please sign in to comment.