FEATURE: Add ignored user list to the User's preference page (#7107)

FEATURE: Add ignored user list to the User’s preference page (#7107)

  • FEATURE: Add ignored user list to the User’s preference page

Why?

Part of: Ability to Ignore a User - feature - Discourse Meta

We want to add list of Ignored users under or along with the muted users preferences section. This way Users can find and update their list of ignored users.

UI

Open questions

Two of many options to represent a list of ignored users is that we can:

  1. We can represent the ignored user list as a table with the ability to un-ignore but NOT to add new ignored users.
  2. We can keep it functioning as the muted user list where you can un-ignore or ignore users.
diff --git a/app/assets/javascripts/discourse/controllers/preferences/users.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/users.js.es6
new file mode 100644
index 0000000..7ecb891
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/preferences/users.js.es6
@@ -0,0 +1,16 @@
+import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+export default Ember.Controller.extend(PreferencesTabController, {
+  saveAttrNames: ["muted_usernames", "ignored_usernames"],
+
+  actions: {
+    save() {
+      this.set("saved", false);
+      return this.get("model")
+        .save(this.get("saveAttrNames"))
+        .then(() => this.set("saved", true))
+        .catch(popupAjaxError);
+    }
+  }
+});
diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
index 160a729..b9fc992 100644
--- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6
+++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
@@ -147,6 +147,7 @@ export default function() {
         this.route("emails");
         this.route("notifications");
         this.route("categories");
+        this.route("users");
         this.route("tags");
         this.route("interface");
         this.route("apps");
diff --git a/app/assets/javascripts/discourse/routes/preferences-users.js.es6 b/app/assets/javascripts/discourse/routes/preferences-users.js.es6
new file mode 100644
index 0000000..713d79e
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/preferences-users.js.es6
@@ -0,0 +1,5 @@
+import RestrictedUserRoute from "discourse/routes/restricted-user";
+
+export default RestrictedUserRoute.extend({
+  showFooter: true
+});
diff --git a/app/assets/javascripts/discourse/templates/preferences.hbs b/app/assets/javascripts/discourse/templates/preferences.hbs
index e714afb..82712f6 100644
--- a/app/assets/javascripts/discourse/templates/preferences.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences.hbs
@@ -25,6 +25,11 @@
         {{i18n 'user.preferences_nav.categories'}}
       {{/link-to}}
     </li>
+    <li class='indent nav-users'>
+      {{#link-to 'preferences.users'}}
+        {{i18n 'user.preferences_nav.users'}}
+      {{/link-to}}
+    </li>
     {{#if siteSettings.tagging_enabled}}
       <li class='indent nav-tags'>
         {{#link-to 'preferences.tags'}}
diff --git a/app/assets/javascripts/discourse/templates/preferences/notifications.hbs b/app/assets/javascripts/discourse/templates/preferences/notifications.hbs
index d4d258c..5c06984 100644
--- a/app/assets/javascripts/discourse/templates/preferences/notifications.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences/notifications.hbs
@@ -39,15 +39,6 @@
   </div>
 {{/if}}
 
-<div class="control-group muting">
-  <label class="control-label">{{i18n 'user.users'}}</label>
-  <div class="controls category-controls">
-    <label>{{d-icon "d-muted" class="muted icon"}} {{i18n 'user.muted_users'}}</label>
-    {{user-selector excludeCurrentUser=true usernames=model.muted_usernames class="user-selector"}}
-  </div>
-  <div class="instructions">{{i18n 'user.muted_users_instructions'}}</div>
-</div>
-
 {{plugin-outlet name="user-preferences-notifications" args=(hash model=model save=(action "save"))}}
 
 <br/>
diff --git a/app/assets/javascripts/discourse/templates/preferences/users.hbs b/app/assets/javascripts/discourse/templates/preferences/users.hbs
new file mode 100644
index 0000000..7249b61
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/preferences/users.hbs
@@ -0,0 +1,29 @@
+<div class="control-group muting">
+  <label class="control-label">{{i18n 'user.users'}}</label>
+  <div class="controls category-controls">
+    <label>{{d-icon "d-muted" class="``icon"}} {{i18n 'user.muted_users'}}</label>
+    {{user-selector excludeCurrentUser=true usernames=model.muted_usernames class="user-selector"}}
+  </div>
+  <div class="instructions">{{i18n 'user.muted_users_instructions'}}</div>
+
+  {{#if siteSettings.ignore_user_enabled}}
+    <div class="controls category-controls">
+      <label>{{d-icon "eye-slash" class="icon"}} {{i18n 'user.ignored_users'}}</label>
+      {{user-selector excludeCurrentUser=true
+                      usernames=model.ignored_usernames class="user-selector"}}
+    </div>
+    <div class="instructions">{{i18n 'user.ignored_users_instructions'}}</div>
+  {{/if}}
+</div>
+
+{{plugin-outlet name="user-preferences-notifications" args=(hash model=model save=(action "save"))}}
+
+<br/>
+
+{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
+
+<div class="control-group save-button">
+  <div class="controls">
+    {{partial 'user/preferences/save-button'}}
+  </div>
+</div>
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index 7f30ead..b4de993 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -112,6 +112,7 @@ class UserSerializer < BasicUserSerializer
                      :custom_avatar_template,
                      :has_title_badges,
                      :muted_usernames,
+                     :ignored_usernames,
                      :mailing_list_posts_per_day,
                      :can_change_bio,
                      :user_api_keys,
@@ -377,6 +378,10 @@ class UserSerializer < BasicUserSerializer
     MutedUser.where(user_id: object.id).joins(:muted_user).pluck(:username)
   end
 
+  def ignored_usernames
+    IgnoredUser.where(user_id: object.id).joins(:ignored_user).pluck(:username)
+  end
+
   def include_private_messages_stats?
     can_edit && !(omit_stats == true)
   end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index a7524bf..e2dfc29 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -722,6 +722,8 @@ en:
       users: "Users"
       muted_users: "Muted"
       muted_users_instructions: "Suppress all notifications from these users."
+      ignored_users: "Ignored"
+      ignored_users_instructions: "Lists all your ignored users."
       muted_topics_link: "Show muted topics"
       watched_topics_link: "Show watched topics"
       tracked_topics_link: "Show tracked topics"
@@ -761,6 +763,7 @@ en:
         emails: "Emails"
         notifications: "Notifications"
         categories: "Categories"
+        users: "Users"
         tags: "Tags"
         interface: "Interface"
         apps: "Apps"
diff --git a/config/routes.rb b/config/routes.rb
index 392400f..49e7f26 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -403,6 +403,7 @@ Discourse::Application.routes.draw do
     get "#{root_path}/:username/preferences/emails" => "users#preferences", constraints: { username: RouteFormat.username }
     get "#{root_path}/:username/preferences/notifications" => "users#preferences", constraints: { username: RouteFormat.username }
     get "#{root_path}/:username/preferences/categories" => "users#preferences", constraints: { username: RouteFormat.username }
+    get "#{root_path}/:username/preferences/users" => "users#preferences", constraints: { username: RouteFormat.username }
     get "#{root_path}/:username/preferences/tags" => "users#preferences", constraints: { username: RouteFormat.username }
     get "#{root_path}/:username/preferences/interface" => "users#preferences", constraints: { username: RouteFormat.username }
     get "#{root_path}/:username/preferences/apps" => "users#preferences", constraints: { username: RouteFormat.username }
diff --git a/config/site_settings.yml b/config/site_settings.yml
index ed2aeda..2acedd3 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -532,6 +532,7 @@ users:
   ignore_user_enabled:
     hidden: true
     default: false
+    client: true
 
 groups:
   enable_group_directory:
diff --git a/test/javascripts/fixtures/user_fixtures.js.es6 b/test/javascripts/fixtures/user_fixtures.js.es6

[... diff too long, it was truncated ...]

GitHub sha: 190b19f3