docbrown/app/services/mentions/create_all.rb
Ben Halpern da6a6739e5
[deploy] Invite users to join and create password (#9294)
* Initial invitation work

* Add more invitation code

* Add proper registration page

* Fix up tests

* Fix failings

* Fix spec

* Add self-serve auth config

* Add registered condition

* Change profile image call and registered_at test

* Change comment

* Fix copy test

* Stub emojipedia

* Linting

* Add registered at to factory

* Ensure registered for user tag

* Update app/views/internal/invitations/index.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/controllers/internal/invitations_controller.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Slight changes

* Update recover password flow

* Update app/views/internal/invitations/index.html.erb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update app/controllers/internal/invitations_controller.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>

* Update db/schema.rb

Co-authored-by: Michael Kohl <citizen428@dev.to>
2020-07-15 11:37:19 -04:00

75 lines
2.2 KiB
Ruby

module Mentions
class CreateAll
def initialize(notifiable)
@notifiable = notifiable
end
def self.call(*args)
new(*args).call
end
def call
# Only works for comments right now.
mentioned_users = users_mentioned_in_text_excluding_author
delete_mentions_removed_from_notifiable_text(mentioned_users)
create_mentions_for(mentioned_users)
end
private
def users_mentioned_in_text_excluding_author
mentioned_usernames = extract_usernames_from_mentions_in_text
collect_existing_users(mentioned_usernames).
yield_self do |existing_mentioned_users|
reject_notifiable_author(existing_mentioned_users)
end
end
def collect_existing_users(usernames)
User.registered.where(username: usernames)
end
def create_mentions_for(users)
users.each { |user| create_mention_for(user) }
end
def extract_usernames_from_mentions_in_text
# Paired with the process that creates the "comment-mentioned-user"
doc = Nokogiri::HTML(notifiable.processed_html)
doc.css(".comment-mentioned-user").map do |link|
link.text.delete("@").downcase
end
end
def reject_notifiable_author(users)
users.reject { |user| authored_by?(user, @notifiable) }
end
def authored_by?(user, notifiable)
user.id == notifiable.user_id
end
def delete_mentions_removed_from_notifiable_text(users)
mentions = @notifiable.mentions.where.not(user_id: users).destroy_all
Notification.remove_all(notifiable_ids: mentions.pluck(:id), notifiable_type: "Mention") if mentions.present?
end
def user_has_comment_notifications?(user)
user.notifications.exists?(notifiable_id: @notifiable.id)
end
def create_mention_for(user)
return if user_has_comment_notifications?(user)
mention = Mention.create(user_id: user.id, mentionable_id: @notifiable.id,
mentionable_type: @notifiable.class.name)
# mentionable_type = model that created the mention, user = user to be mentioned
Notification.send_mention_notification(mention)
mention
end
attr_reader :notifiable
end
end