UX: adds visual feedback when changing topic notifications level (#9831)

UX: adds visual feedback when changing topic notifications level (#9831)

diff --git a/app/assets/javascripts/discourse/app/models/topic-details.js b/app/assets/javascripts/discourse/app/models/topic-details.js
index 50449aa..45dd194 100644
--- a/app/assets/javascripts/discourse/app/models/topic-details.js
+++ b/app/assets/javascripts/discourse/app/models/topic-details.js
@@ -61,12 +61,14 @@ const TopicDetails = RestModel.extend({
     }
   },
 
-  updateNotifications(v) {
-    this.set("notification_level", v);
-    this.set("notifications_reason_id", null);
-    return ajax("/t/" + this.get("topic.id") + "/notifications", {
+  updateNotifications(level) {
+    this.setProperties({
+      notification_level: level,
+      notifications_reason_id: null
+    });
+    return ajax(`/t/${this.get("topic.id")}/notifications`, {
       type: "POST",
-      data: { notification_level: v }
+      data: { notification_level: level }
     });
   },
 
diff --git a/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js b/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js
index 5832939..a8743d8 100644
--- a/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js
+++ b/app/assets/javascripts/select-kit/app/components/topic-notifications-button.js
@@ -1,20 +1,38 @@
 import Component from "@ember/component";
-import { action } from "@ember/object";
+import { action, computed } from "@ember/object";
+import { later, cancel } from "@ember/runloop";
 
 export default Component.extend({
   layoutName: "select-kit/templates/components/topic-notifications-button",
   classNames: ["topic-notifications-button"],
+  classNameBindings: ["isLoading"],
   appendReason: true,
   showFullTitle: true,
   placement: "bottom-start",
   notificationLevel: null,
   topic: null,
   showCaret: true,
+  isLoading: false,
+  icon: computed("isLoading", function() {
+    return this.isLoading ? "spinner" : null;
+  }),
+
+  willDestroyElement() {
+    this._super(...arguments);
+
+    this._endLoadingHandler && cancel(this._endLoadingHandler);
+  },
 
   @action
   changeTopicNotificationLevel(levelId) {
     if (levelId !== this.notificationLevel) {
-      this.topic.details.updateNotifications(levelId);
+      this.set("isLoading", true);
+      this.topic.details.updateNotifications(levelId).finally(() => {
+        this._endLoadingHandler = later(
+          () => this.set("isLoading", false),
+          250
+        );
+      });
     }
   }
 });
diff --git a/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs b/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs
index fa6f3e8..f21111e 100644
--- a/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs
+++ b/app/assets/javascripts/select-kit/app/templates/components/topic-notifications-button.hbs
@@ -5,6 +5,7 @@
       topic=topic
       onChange=(action "changeTopicNotificationLevel")
       options=(hash
+        icon=icon
         showFullTitle=showFullTitle
         placement=placement
         preventsClickPropagation=true
@@ -19,6 +20,7 @@
     topic=topic
     onChange=(action "changeTopicNotificationLevel")
     options=(hash
+      icon=icon
       showFullTitle=showFullTitle
       placement=placement
       preventsClickPropagation=true
diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss
index 54aa976..a290f2c 100644
--- a/app/assets/stylesheets/common/base/topic-post.scss
+++ b/app/assets/stylesheets/common/base/topic-post.scss
@@ -1026,6 +1026,14 @@ a.mention-group {
     margin-top: 0;
   }
 
+  .topic-notifications-button.is-loading {
+    pointer-events: none;
+    user-select: none;
+    .topic-notifications-options {
+      opacity: 0.5;
+    }
+  }
+
   .pinned-button,
   .topic-notifications-button {
     margin: 1em 0;
diff --git a/app/assets/stylesheets/common/select-kit/select-kit.scss b/app/assets/stylesheets/common/select-kit/select-kit.scss
index 130bad5..a9769b5 100644
--- a/app/assets/stylesheets/common/select-kit/select-kit.scss
+++ b/app/assets/stylesheets/common/select-kit/select-kit.scss
@@ -63,6 +63,11 @@
     flex-direction: row;
     min-height: 30px;
 
+    .d-icon-spinner {
+      -webkit-animation: rotate-forever 1s infinite linear;
+      animation: rotate-forever 1s infinite linear;
+    }
+
     .selected-name {
       text-align: left;
       flex: 0 1 auto;

GitHub sha: 7c3663ff

1 Like

This commit appears in #9831 which was merged by jjaffeux.