FEATURE: Introducing new UI for changing User's notification levels (#7248)

FEATURE: Introducing new UI for changing User’s notification levels (#7248)

  • FEATURE: Introducing new UI for tracking User’s ignored or muted states
diff --git a/app/assets/javascripts/discourse/controllers/user.js.es6 b/app/assets/javascripts/discourse/controllers/user.js.es6
index 48d2711..038dfcc 100644
--- a/app/assets/javascripts/discourse/controllers/user.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user.js.es6
@@ -33,7 +33,10 @@ export default Ember.Controller.extend(CanCheckEmails, {
     }
     return (!indexStream || viewingSelf) && !forceExpand;
   },
-
+  canMuteOrIgnoreUser: Ember.computed.or(
+    "model.can_ignore_user",
+    "model.can_mute_user"
+  ),
   hasGivenFlags: Ember.computed.gt("model.number_of_flags_given", 0),
   hasFlaggedPosts: Ember.computed.gt("model.number_of_flagged_posts", 0),
   hasDeletedPosts: Ember.computed.gt("model.number_of_deleted_posts", 0),
@@ -147,14 +150,9 @@ export default Ember.Controller.extend(CanCheckEmails, {
       this.get("adminTools").deleteUser(this.get("model.id"));
     },
 
-    ignoreUser() {
-      const user = this.get("model");
-      user.ignore().then(() => user.set("ignored", true));
-    },
-
-    unignoreUser() {
+    updateNotificationLevel(level) {
       const user = this.get("model");
-      user.unignore().then(() => user.set("ignored", false));
+      return user.updateNotificationLevel(level);
     }
   }
 });
diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6
index 1405295..72da24d 100644
--- a/app/assets/javascripts/discourse/models/user.js.es6
+++ b/app/assets/javascripts/discourse/models/user.js.es6
@@ -615,17 +615,10 @@ const User = RestModel.extend({
     }
   },
 
-  ignore() {
-    return ajax(`${userPath(this.get("username"))}/ignore.json`, {
+  updateNotificationLevel(level) {
+    return ajax(`${userPath(this.get("username"))}/notification_level.json`, {
       type: "PUT",
-      data: { ignored_user_id: this.get("id") }
-    });
-  },
-
-  unignore() {
-    return ajax(`${userPath(this.get("username"))}/ignore.json`, {
-      type: "DELETE",
-      data: { ignored_user_id: this.get("id") }
+      data: { notification_level: level }
     });
   },
 
diff --git a/app/assets/javascripts/discourse/templates/user.hbs b/app/assets/javascripts/discourse/templates/user.hbs
index 0c3669d..1a7afc3 100644
--- a/app/assets/javascripts/discourse/templates/user.hbs
+++ b/app/assets/javascripts/discourse/templates/user.hbs
@@ -48,19 +48,9 @@
                     icon="envelope"
                     label="user.private_message"}}
                 </li>
-                {{#if model.can_ignore_user}}
+                {{#if canMuteOrIgnoreUser}}
                   <li>
-                  {{#if model.ignored}}
-                    {{d-button class="btn-default"
-                               action=(action "unignoreUser")
-                               icon="far-eye"
-                               label="user.unignore"}}
-                  {{else}}
-                    {{d-button class="btn-default"
-                               action=(action "ignoreUser")
-                               icon="eye-slash"
-                               label="user.ignore"}}
-                  {{/if}}
+                    {{user-notifications-dropdown user=model updateNotificationLevel=(action "updateNotificationLevel")}}
                   </li>
                 {{/if}}
               {{/if}}
diff --git a/app/assets/javascripts/select-kit/components/user-notifications-dropdown.js.es6 b/app/assets/javascripts/select-kit/components/user-notifications-dropdown.js.es6
new file mode 100644
index 0000000..4f90a2e
--- /dev/null
+++ b/app/assets/javascripts/select-kit/components/user-notifications-dropdown.js.es6
@@ -0,0 +1,85 @@
+import DropdownSelectBox from "select-kit/components/dropdown-select-box";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+export default DropdownSelectBox.extend({
+  classNames: ["user-notifications", "user-notifications-dropdown"],
+  nameProperty: "label",
+  allowInitialValueMutation: false,
+
+  computeHeaderContent() {
+    let content = this._super(...arguments);
+    if (this.get("user.ignored")) {
+      this.set("headerIcon", "eye-slash");
+      content.name = `${I18n.t("user.user_notifications_ignore_option")}`;
+    } else if (this.get("user.muted")) {
+      this.set("headerIcon", "times-circle");
+      content.name = `${I18n.t("user.user_notifications_mute_option")}`;
+    } else {
+      this.set("headerIcon", "user");
+      content.name = `${I18n.t("user.user_notifications_normal_option")}`;
+    }
+    return content;
+  },
+
+  computeContent() {
+    const content = [];
+
+    content.push({
+      icon: "user",
+      id: "change-to-normal",
+      description: I18n.t("user.user_notifications_normal_option_title"),
+      action: () => this.send("reset"),
+      label: I18n.t("user.user_notifications_normal_option")
+    });
+
+    content.push({
+      icon: "times-circle",
+      id: "change-to-muted",
+      description: I18n.t("user.user_notifications_mute_option_title"),
+      action: () => this.send("mute"),
+      label: I18n.t("user.user_notifications_mute_option")
+    });
+
+    if (this.get("user.can_ignore_user")) {
+      content.push({
+        icon: "eye-slash",
+        id: "change-to-ignored",
+        description: I18n.t("user.user_notifications_ignore_option_title"),
+        action: () => this.send("ignore"),
+        label: I18n.t("user.user_notifications_ignore_option")
+      });
+    }
+
+    return content;
+  },
+
+  actions: {
+    reset() {
+      this.get("updateNotificationLevel")("normal")
+        .then(() => {
+          this.set("user.ignored", false);
+          this.set("user.muted", false);
+          this.computeHeaderContent();
+        })
+        .catch(popupAjaxError);
+    },
+    mute() {
+      this.get("updateNotificationLevel")("mute")
+        .then(() => {
+          this.set("user.ignored", false);
+          this.set("user.muted", true);
+          this.computeHeaderContent();
+        })
+        .catch(popupAjaxError);
+    },
+    ignore() {
+      this.get("updateNotificationLevel")("ignore")
+        .then(() => {
+          this.set("user.ignored", true);
+          this.set("user.muted", false);
+          this.computeHeaderContent();
+        })
+        .catch(popupAjaxError);
+    }
+  }
+});
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 050d1c3..c23f180 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -27,6 +27,7 @@
 @import "common/select-kit/tag-drop";
 @import "common/select-kit/toolbar-popup-menu-options";
 @import "common/select-kit/topic-notifications-button";
+@import "common/select-kit/user-notifications-dropdown";
 @import "common/select-kit/color-palettes";
 @import "common/components/*";
 @import "common/input_tip";
diff --git a/app/assets/stylesheets/common/base/user.scss b/app/assets/stylesheets/common/base/user.scss
index 6212048..050a3ad 100644
--- a/app/assets/stylesheets/common/base/user.scss
+++ b/app/assets/stylesheets/common/base/user.scss
@@ -97,7 +97,6 @@
 
 .user-main {
   .about {
-    overflow: hidden;
     width: 100%;
     margin-bottom: 15px;
 
diff --git a/app/assets/stylesheets/common/select-kit/user-notifications-dropdown.scss b/app/assets/stylesheets/common/select-kit/user-notifications-dropdown.scss
new file mode 100644
index 0000000..a529f38
--- /dev/null
+++ b/app/assets/stylesheets/common/select-kit/user-notifications-dropdown.scss
@@ -0,0 +1,20 @@
+.select-kit {
+  &.dropdown-select-box {
+    &.user-notifications-dropdown {
+      text-align: left;
+
+      .select-kit-body {
+        width: 485px;
+        max-width: 485px;
+      }
+
+      .select-kit-header {
+        justify-content: center;
+      }
+
+      .dropdown-select-box-header {
+        align-items: center;
+      }
+    }
+  }
+}
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 239388c..d55d07a 100644
--- a/app/controllers/users_controller.rb

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

GitHub sha: ef2362a3