Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mentions in comments backend changes #6818

Merged
merged 3 commits into from Nov 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 17 additions & 4 deletions app/controllers/notifications_controller.rb
Expand Up @@ -23,8 +23,8 @@ def update

def index
conditions = {:recipient_id => current_user.id}
if params[:type] && Notification.types.has_key?(params[:type])
conditions[:type] = Notification.types[params[:type]]
if params[:type] && types.has_key?(params[:type])
conditions[:type] = types[params[:type]]
end
if params[:show] == "unread" then conditions[:unread] = true end
page = params[:page] || 1
Expand All @@ -44,7 +44,7 @@ def index

@grouped_unread_notification_counts = {}

Notification.types.each_with_object(current_user.unread_notifications.group_by(&:type)) {|(name, type), notifications|
types.each_with_object(current_user.unread_notifications.group_by(&:type)) {|(name, type), notifications|
@grouped_unread_notification_counts[name] = notifications.has_key?(type) ? notifications[type].count : 0
}

Expand All @@ -65,7 +65,7 @@ def default_serializer_options
end

def read_all
current_type = Notification.types[params[:type]]
current_type = types[params[:type]]
notifications = Notification.where(recipient_id: current_user.id, unread: true)
notifications = notifications.where(type: current_type) if params[:type]
notifications.update_all(unread: false)
Expand Down Expand Up @@ -93,4 +93,17 @@ def render_as_json(unread_count, unread_count_by_type, notification_list)
}
}.as_json
end

def types
{
"also_commented" => "Notifications::AlsoCommented",
"comment_on_post" => "Notifications::CommentOnPost",
"liked" => "Notifications::Liked",
"mentioned" => "Notifications::MentionedInPost",
"mentioned_in_comment" => "Notifications::MentionedInComment",
"reshared" => "Notifications::Reshared",
"started_sharing" => "Notifications::StartedSharing"
}
end
helper_method :types
end
5 changes: 4 additions & 1 deletion app/controllers/status_messages_controller.rb
Expand Up @@ -80,7 +80,10 @@ def handle_create_error(error)

def handle_mention_feedback(status_message)
return unless comes_from_others_profile_page?
flash[:notice] = t("status_messages.create.success", names: status_message.mentioned_people_names)
flash[:notice] = t(
"status_messages.create.success",
names: PersonPresenter.people_names(status_message.mentioned_people)
)
end

def comes_from_others_profile_page?
Expand Down
11 changes: 1 addition & 10 deletions app/controllers/users_controller.rb
Expand Up @@ -150,16 +150,7 @@ def user_params
:auto_follow_back_aspect_id,
:getting_started,
:post_default_public,
email_preferences: %i(
someone_reported
also_commented
mentioned
comment_on_post
private_message
started_sharing
liked
reshared
)
email_preferences: UserPreference::VALID_EMAIL_TYPES.map(&:to_sym)
)
end
# rubocop:enable Metrics/MethodLength
Expand Down
56 changes: 30 additions & 26 deletions app/helpers/notifications_helper.rb
Expand Up @@ -2,42 +2,46 @@ module NotificationsHelper
include PeopleHelper
include PostsHelper

def object_link(note, actors)
def object_link(note, actors_html)
target_type = note.popup_translation_key
actors_count = note.actors.size
opts = {actors: actors_html, count: note.actors.size}

if note.instance_of?(Notifications::Mentioned)
if post = note.linked_object
translation(target_type,
actors: actors,
count: actors_count,
post_link: link_to(post_page_title(post), post_path(post)).html_safe)
else
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
if note.respond_to?(:linked_object)
if note.linked_object.nil? && note.respond_to?(:deleted_translation_key)
target_type = note.deleted_translation_key
elsif note.is_a?(Notifications::Mentioned)
opts.merge!(opts_for_mentioned(note.linked_object))
elsif %w(Notifications::CommentOnPost Notifications::AlsoCommented Notifications::Reshared Notifications::Liked)
.include?(note.type)
opts.merge!(opts_for_post(note.linked_object))
end
elsif note.instance_of?(Notifications::CommentOnPost) || note.instance_of?(Notifications::AlsoCommented) || note.instance_of?(Notifications::Reshared) || note.instance_of?(Notifications::Liked)
if post = note.linked_object
translation(target_type,
actors: actors,
count: actors_count,
post_author: h(post.author_name),
post_link: link_to(post_page_title(post),
post_path(post),
data: {ref: post.id},
class: "hard_object_link").html_safe)
else
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
end
else #Notifications:StartedSharing, etc.
translation(target_type, :actors => actors, :count => actors_count)
end
translation(target_type, opts)
end

def translation(target_type, opts = {})
{:post_author => nil}.merge!(opts)
t("#{target_type}", opts).html_safe
end

def opts_for_post(post)
{
post_author: html_escape(post.author_name),
post_link: link_to(post_page_title(post),
post_path(post),
data: {ref: post.id},
class: "hard_object_link").html_safe
}
end

def opts_for_mentioned(mentioned)
post = mentioned.instance_of?(Comment) ? mentioned.parent : mentioned
{
post_link: link_to(post_page_title(post), post_path(post)).html_safe
}.tap {|opts|
opts[:comment_path] = post_path(post, anchor: mentioned.guid).html_safe if mentioned.instance_of?(Comment)
}
end

def notification_people_link(note, people=nil)
actors =people || note.actors
number_of_actors = actors.size
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/notification_mailers/mentioned.rb
Expand Up @@ -4,7 +4,7 @@ class Mentioned < NotificationMailers::Base
delegate :author_name, to: :post, prefix: true

def set_headers(target_id)
@post = Mention.find_by_id(target_id).post
@post = Mention.find_by_id(target_id).mentions_container

@headers[:subject] = I18n.t('notifier.mentioned.subject', :name => @sender.name)
@headers[:in_reply_to] = @headers[:references] = "<#{@post.guid}@#{AppConfig.pod_uri.host}>"
Expand Down
11 changes: 11 additions & 0 deletions app/mailers/notification_mailers/mentioned_in_comment.rb
@@ -0,0 +1,11 @@
module NotificationMailers
class MentionedInComment < NotificationMailers::Base
attr_reader :comment

def set_headers(target_id) # rubocop:disable Style/AccessorMethodName
@comment = Mention.find_by_id(target_id).mentions_container

@headers[:subject] = I18n.t("notifier.mentioned.subject", name: @sender.name)
end
end
end
4 changes: 2 additions & 2 deletions app/mailers/notification_mailers/started_sharing.rb
@@ -1,7 +1,7 @@
module NotificationMailers
class StartedSharing < NotificationMailers::Base
def set_headers
@headers[:subject] = I18n.t('notifier.started_sharing.subject', :name => @sender.name)
def set_headers(*_args) # rubocop:disable Style/AccessorMethodName
@headers[:subject] = I18n.t("notifier.started_sharing.subject", name: @sender.name)
end
end
end
40 changes: 3 additions & 37 deletions app/mailers/notifier.rb
Expand Up @@ -55,54 +55,20 @@ def invite(email, message, inviter, invitation_code, locale)
end
end

def started_sharing(recipient_id, sender_id)
send_notification(:started_sharing, recipient_id, sender_id)
end

def liked(recipient_id, sender_id, like_id)
send_notification(:liked, recipient_id, sender_id, like_id)
end

def reshared(recipient_id, sender_id, reshare_id)
send_notification(:reshared, recipient_id, sender_id, reshare_id)
end

def mentioned(recipient_id, sender_id, target_id)
send_notification(:mentioned, recipient_id, sender_id, target_id)
end

def comment_on_post(recipient_id, sender_id, comment_id)
send_notification(:comment_on_post, recipient_id, sender_id, comment_id)
end

def also_commented(recipient_id, sender_id, comment_id)
send_notification(:also_commented, recipient_id, sender_id, comment_id)
end

def private_message(recipient_id, sender_id, message_id)
send_notification(:private_message, recipient_id, sender_id, message_id)
end

def confirm_email(recipient_id)
send_notification(:confirm_email, recipient_id)
end

def csrf_token_fail(recipient_id)
send_notification(:csrf_token_fail, recipient_id)
end

private
def send_notification(type, *args)
@notification = NotificationMailers.const_get(type.to_s.camelize).new(*args)

with_recipient_locale do
mail(@notification.headers) do |format|
self.action_name = type
format.text
format.html
end
end
end

private

def with_recipient_locale(&block)
I18n.with_locale(@notification.recipient.language, &block)
end
Expand Down
19 changes: 14 additions & 5 deletions app/models/comment.rb
Expand Up @@ -11,6 +11,7 @@ class Comment < ActiveRecord::Base

include Diaspora::Taggable
include Diaspora::Likeable
include Diaspora::MentionsContainer

acts_as_taggable_on :tags
extract_tags_from :text
Expand Down Expand Up @@ -49,14 +50,22 @@ class Comment < ActiveRecord::Base
participation.unparticipate! if participation.present?
end

def message
@message ||= Diaspora::MessageRenderer.new text
end

def text= text
self[:text] = text.to_s.strip #to_s if for nil, for whatever reason
end

def people_allowed_to_be_mentioned
if parent.public?
:all
else
[*parent.comments.pluck(:author_id), *parent.likes.pluck(:author_id), parent.author_id].uniq
end
end

def add_mention_subscribers?
super && parent.author.local?
end

class Generator < Diaspora::Federated::Generator
def self.federated_class
Comment
Expand All @@ -68,7 +77,7 @@ def initialize(person, target, text)
end

def relayable_options
{:post => @target, :text => @text}
{post: @target, text: @text}
end
end
end
8 changes: 6 additions & 2 deletions app/models/mention.rb
Expand Up @@ -3,11 +3,15 @@
# the COPYRIGHT file.

class Mention < ActiveRecord::Base
belongs_to :post
belongs_to :mentions_container, polymorphic: true
belongs_to :person
validates :post, presence: true
validates :mentions_container, presence: true
validates :person, presence: true

scope :local, -> {
joins(:person).where.not(people: {owner_id: nil})
}

after_destroy :delete_notification

def delete_notification
Expand Down
11 changes: 0 additions & 11 deletions app/models/notification.rb
Expand Up @@ -51,15 +51,4 @@ def self.create_notification(recipient, target, actor)
private_class_method def self.suppress_notification?(recipient, actor)
recipient.blocks.where(person: actor).exists?
end

def self.types
{
"also_commented" => "Notifications::AlsoCommented",
"comment_on_post" => "Notifications::CommentOnPost",
"liked" => "Notifications::Liked",
"mentioned" => "Notifications::Mentioned",
"reshared" => "Notifications::Reshared",
"started_sharing" => "Notifications::StartedSharing"
}
end
end
8 changes: 3 additions & 5 deletions app/models/notifications/also_commented.rb
@@ -1,5 +1,7 @@
module Notifications
class AlsoCommented < Notification
include Notifications::Commented

def mail_job
Workers::Mail::AlsoCommented
end
Expand All @@ -8,17 +10,13 @@ def popup_translation_key
"notifications.also_commented"
end

def deleted_translation_key
"notifications.also_commented_deleted"
end

def self.notify(comment, _recipient_user_ids)
actor = comment.author
commentable = comment.commentable
recipient_ids = commentable.participants.local.where.not(id: [commentable.author_id, actor.id]).pluck(:owner_id)

User.where(id: recipient_ids).find_each do |recipient|
next if recipient.is_shareable_hidden?(commentable)
next if recipient.is_shareable_hidden?(commentable) || mention_notification_exists?(comment, recipient.person)

concatenate_or_create(recipient, commentable, actor).try(:email_the_user, comment, actor)
end
Expand Down
7 changes: 3 additions & 4 deletions app/models/notifications/comment_on_post.rb
@@ -1,5 +1,7 @@
module Notifications
class CommentOnPost < Notification
include Notifications::Commented

def mail_job
Workers::Mail::CommentOnPost
end
Expand All @@ -8,15 +10,12 @@ def popup_translation_key
"notifications.comment_on_post"
end

def deleted_translation_key
"notifications.also_commented_deleted"
end

def self.notify(comment, _recipient_user_ids)
actor = comment.author
commentable_author = comment.commentable.author

return unless commentable_author.local? && actor != commentable_author
return if mention_notification_exists?(comment, commentable_author)

concatenate_or_create(commentable_author.owner, comment.commentable, actor).email_the_user(comment, actor)
end
Expand Down
15 changes: 15 additions & 0 deletions app/models/notifications/commented.rb
@@ -0,0 +1,15 @@
module Notifications
module Commented
extend ActiveSupport::Concern

def deleted_translation_key
"notifications.also_commented_deleted"
end

module ClassMethods
def mention_notification_exists?(comment, recipient_person)
Notifications::MentionedInComment.exists?(target: comment.mentions.where(person: recipient_person))
end
end
end
end