FEATURE: Save ignored usernames in user preferences (#7117)

FEATURE: Save ignored usernames in user preferences (#7117)

  • FEATURE: Save ignored usernames in user preferences
diff --git a/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
index de4f841..c680a31 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
@@ -5,6 +5,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
 export default Ember.Controller.extend(PreferencesTabController, {
   saveAttrNames: [
     "muted_usernames",
+    "ignored_usernames",
     "new_topic_duration_minutes",
     "auto_track_topics_after_msecs",
     "notification_level_when_replying",
diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6
index 18963d7..2e5fa5d 100644
--- a/app/assets/javascripts/discourse/models/user.js.es6
+++ b/app/assets/javascripts/discourse/models/user.js.es6
@@ -249,6 +249,7 @@ const User = RestModel.extend({
       "custom_fields",
       "user_fields",
       "muted_usernames",
+      "ignored_usernames",
       "profile_background",
       "card_background",
       "muted_tags",
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index de10323..9be7ef9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1226,6 +1226,7 @@ class UsersController < ApplicationController
       :title,
       :date_of_birth,
       :muted_usernames,
+      :ignored_usernames,
       :theme_ids,
       :locale,
       :bio_raw,
diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb
index 52df88f..261634a 100644
--- a/app/services/user_updater.rb
+++ b/app/services/user_updater.rb
@@ -128,6 +128,10 @@ class UserUpdater
         update_muted_users(attributes[:muted_usernames])
       end
 
+      if attributes.key?(:ignored_usernames)
+        update_ignored_users(attributes[:ignored_usernames])
+      end
+
       name_changed = user.name_changed?
       if (saved = (!save_options || user.user_option.save) && user_profile.save && user.save) &&
          (name_changed && old_user_name.casecmp(attributes.fetch(:name)) != 0)
@@ -157,13 +161,27 @@ class UserUpdater
         INSERT into muted_users(user_id, muted_user_id, created_at, updated_at)
         SELECT :user_id, id, :now, :now
         FROM users
-        WHERE
-          id in (:desired_ids) AND
-          id NOT IN (
-            SELECT muted_user_id
-            FROM muted_users
-            WHERE user_id = :user_id
-          )
+        WHERE id in (:desired_ids)
+        ON CONFLICT DO NOTHING
+      SQL
+    end
+  end
+
+  def update_ignored_users(usernames)
+    usernames ||= ""
+    desired_ids = User.where(username: usernames.split(",")).pluck(:id)
+    if desired_ids.empty?
+      IgnoredUser.where(user_id: user.id).destroy_all
+    else
+      IgnoredUser.where('user_id = ? AND ignored_user_id not in (?)', user.id, desired_ids).destroy_all
+
+      # SQL is easier here than figuring out how to do the same in AR
+      DB.exec(<<~SQL, now: Time.now, user_id: user.id, desired_ids: desired_ids)
+        INSERT into ignored_users(user_id, ignored_user_id, created_at, updated_at)
+        SELECT :user_id, id, :now, :now
+        FROM users
+        WHERE id in (:desired_ids)
+        ON CONFLICT DO NOTHING
       SQL
     end
   end
diff --git a/spec/services/user_updater_spec.rb b/spec/services/user_updater_spec.rb
index 609099a..d4a10da 100644
--- a/spec/services/user_updater_spec.rb
+++ b/spec/services/user_updater_spec.rb
@@ -22,7 +22,27 @@ describe UserUpdater do
       expect(MutedUser.where(user_id: u2.id).count).to eq 2
       expect(MutedUser.where(user_id: u1.id).count).to eq 2
       expect(MutedUser.where(user_id: u3.id).count).to eq 0
+    end
+  end
+
+  describe '#update_ignored_users' do
+    it 'updates ignored users' do
+      u1 = Fabricate(:user)
+      u2 = Fabricate(:user)
+      u3 = Fabricate(:user)
+
+      updater = UserUpdater.new(u1, u1)
+      updater.update_ignored_users("#{u2.username},#{u3.username}")
+
+      updater = UserUpdater.new(u2, u2)
+      updater.update_ignored_users("#{u3.username},#{u1.username}")
+
+      updater = UserUpdater.new(u3, u3)
+      updater.update_ignored_users("")
 
+      expect(IgnoredUser.where(user_id: u2.id).count).to eq 2
+      expect(IgnoredUser.where(user_id: u1.id).count).to eq 2
+      expect(IgnoredUser.where(user_id: u3.id).count).to eq 0
     end
   end

GitHub sha: 0a9a1109