FEATURE: Ignoring users from the preferences page in a cleaner way (#7289)

FEATURE: Ignoring users from the preferences page in a cleaner way (#7289)

  • FEATURE: Ignoring users from the preferences page in a cleaner way
diff --git a/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6 b/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6
new file mode 100644
index 0000000..8a41fe7
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6
@@ -0,0 +1,9 @@
+export default Ember.Component.extend({
+  tagName: "div",
+  items: null,
+  actions: {
+    removeIgnoredUser(item) {
+      this.get("onRemoveIgnoredUser")(item);
+    }
+  }
+});
diff --git a/app/assets/javascripts/discourse/components/ignored-user-list.js.es6 b/app/assets/javascripts/discourse/components/ignored-user-list.js.es6
new file mode 100644
index 0000000..5fd0a6f
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/ignored-user-list.js.es6
@@ -0,0 +1,29 @@
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import showModal from "discourse/lib/show-modal";
+import User from "discourse/models/user";
+
+export default Ember.Component.extend({
+  item: null,
+  actions: {
+    removeIgnoredUser(item) {
+      this.set("saved", false);
+      this.get("items").removeObject(item);
+      User.findByUsername(item).then(user => {
+        user
+          .updateNotificationLevel("normal")
+          .catch(popupAjaxError)
+          .finally(() => this.set("saved", true));
+      });
+    },
+    newIgnoredUser() {
+      const modal = showModal("ignore-duration-with-username", {
+        model: this.get("model")
+      });
+      modal.setProperties({
+        onUserIgnored: username => {
+          this.get("items").addObject(username);
+        }
+      });
+    }
+  }
+});
diff --git a/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6 b/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6
new file mode 100644
index 0000000..fc1f8ce
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6
@@ -0,0 +1,31 @@
+import ModalFunctionality from "discourse/mixins/modal-functionality";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import User from "discourse/models/user";
+
+export default Ember.Controller.extend(ModalFunctionality, {
+  loading: false,
+  ignoredUntil: null,
+  ignoredUsername: null,
+  actions: {
+    ignore() {
+      if (!this.get("ignoredUntil") || !this.get("ignoredUsername")) {
+        this.flash(
+          I18n.t("user.user_notifications.ignore_duration_time_frame_required"),
+          "alert-error"
+        );
+        return;
+      }
+      this.set("loading", true);
+      User.findByUsername(this.get("ignoredUsername")).then(user => {
+        user
+          .updateNotificationLevel("ignore", this.get("ignoredUntil"))
+          .then(() => {
+            this.onUserIgnored(this.get("ignoredUsername"));
+            this.send("closeModal");
+          })
+          .catch(popupAjaxError)
+          .finally(() => this.set("loading", false));
+      });
+    }
+  }
+});
diff --git a/app/assets/javascripts/discourse/templates/components/ignored-user-list-item.hbs b/app/assets/javascripts/discourse/templates/components/ignored-user-list-item.hbs
new file mode 100644
index 0000000..eb85b54
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/ignored-user-list-item.hbs
@@ -0,0 +1,4 @@
+<div class="ignored-user-list-item">
+  <span class="ignored-user-name">{{item}}</span>
+  {{d-button class="remove-ignored-user no-text btn-icon" action=(action "removeIgnoredUser" item) icon="times"}}
+</div>
diff --git a/app/assets/javascripts/discourse/templates/components/ignored-user-list.hbs b/app/assets/javascripts/discourse/templates/components/ignored-user-list.hbs
new file mode 100644
index 0000000..12e1f06
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/ignored-user-list.hbs
@@ -0,0 +1,9 @@
+<div class="ignored-list">
+  {{#each items as |item|}}
+    {{ignored-user-list-item item=item onRemoveIgnoredUser=(action "removeIgnoredUser")}}
+  {{else}}
+    {{i18n 'user.user_notifications.ignore_no_users'}}
+  {{/each}}
+</div>
+<div class="instructions">{{i18n 'user.ignored_users_instructions'}}</div>
+<div>{{#d-button action=(action "newIgnoredUser") class="btn-default" icon="plus"}}{{i18n 'user.user_notifications.add_ignored_user'}}{{/d-button}}</div>
diff --git a/app/assets/javascripts/discourse/templates/modal/ignore-duration-with-username.hbs b/app/assets/javascripts/discourse/templates/modal/ignore-duration-with-username.hbs
new file mode 100644
index 0000000..40a2826
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/modal/ignore-duration-with-username.hbs
@@ -0,0 +1,25 @@
+{{#d-modal-body title="user.user_notifications.ignore_duration_title" autoFocus="false"}}
+  <div class="controls tracking-controls">
+    <label>{{d-icon "eye-slash" class="icon"}} {{i18n "user.user_notifications.ignore_duration_username"}}</label>
+    {{user-selector excludeCurrentUser=true
+                    single="true"
+                    usernames=ignoredUsername
+                    class="user-selector"}}
+  </div>
+  {{future-date-input
+    label="user.user_notifications.ignore_duration_when"
+    input=ignoredUntil
+    includeWeekend=true
+    includeDateTime=false
+    includeMidFuture=true
+    includeFarFuture=false}}
+  <p>{{i18n "user.user_notifications.ignore_duration_note"}}</p>
+{{/d-modal-body}}
+
+<div class="modal-footer">
+  {{d-button class="btn-primary"
+             disabled=saveDisabled
+             label="user.user_notifications.ignore_duration_save"
+             action=(action "ignore")}}
+  {{conditional-loading-spinner size="small" condition=loading}}
+</div>
diff --git a/app/assets/javascripts/discourse/templates/preferences/users.hbs b/app/assets/javascripts/discourse/templates/preferences/users.hbs
index 07b3109..6d77e2b 100644
--- a/app/assets/javascripts/discourse/templates/preferences/users.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences/users.hbs
@@ -1,27 +1,16 @@
 <label class="control-label">{{i18n 'user.users'}}</label>
 <div class="control-group">
   <div class="controls tracking-controls">
-    <label>{{d-icon "d-muted" class="``icon"}} {{i18n 'user.muted_users'}}</label>
+    <label>
+      {{d-icon "d-muted" class="icon"}}
+      <span>{{i18n 'user.muted_users'}}</span>
+    </label>
     {{user-selector excludeCurrentUser=true usernames=model.muted_usernames class="user-selector"}}
   </div>
   <div class="instructions">{{i18n 'user.muted_users_instructions'}}</div>
-
-  {{#if ignoredEnabled}}
-    <div class="controls tracking-controls">
-      <label>{{d-icon "eye-slash" class="icon"}} {{i18n 'user.ignored_users'}}</label>
-      {{user-selector excludeCurrentUser=true
-                      usernames=model.ignored_usernames
-                      onChangeCallback=(action "ignoredUsernamesChanged")
-                      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">
@@ -29,3 +18,12 @@
     {{partial 'user/preferences/save-button'}}
   </div>
 </div>
+
+{{#if ignoredEnabled}}
+  <div class="control-group">
+    <div class="controls tracking-controls">
+      <label>{{d-icon "eye-slash" class="icon"}} {{i18n 'user.ignored_users'}}</label>
+      {{ignored-user-list model=model items=model.ignored_usernames saving=saved}}
+    </div>
+  </div>
+{{/if}}
diff --git a/app/assets/stylesheets/common/components/ignored-user-list.scss b/app/assets/stylesheets/common/components/ignored-user-list.scss
new file mode 100644
index 0000000..a0723fe
--- /dev/null
+++ b/app/assets/stylesheets/common/components/ignored-user-list.scss
@@ -0,0 +1,36 @@
+.ignored-list {
+  overflow: auto;
+  max-height: 150px;
+  display: flex;
+  flex-wrap: wrap;

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

GitHub sha: d8ff94ec

DEV: Remove unused action from user preferences controller