DEV: Allow callback to be registered to remove post menu button. (#15061)

DEV: Allow callback to be registered to remove post menu button. (#15061)

This will allow buttons in the post menu to be remove based on a post’s attributes or site settings.

diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js
index 6b16d72..e869e47 100644
--- a/app/assets/javascripts/discourse/app/lib/plugin-api.js
+++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js
@@ -94,7 +94,7 @@ import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
 import { downloadCalendar } from "discourse/lib/download-calendar";
 
 // If you add any methods to the API ensure you bump up this number
-const PLUGIN_API_VERSION = "0.13.1";
+const PLUGIN_API_VERSION = "0.14.0";
 
 // This helper prevents us from applying the same `modifyClass` over and over in test mode.
 function canModify(klass, type, resolverName, changes) {
@@ -490,9 +490,17 @@ class PluginApi {
    * `‍``
    * api.removePostMenuButton('like');
    * `‍``
+   *
+   * `‍``
+   * api.removePostMenuButton('like', (attrs, state, siteSettings, settings, currentUser) => {
+   *   if (attrs.post_number === 1) {
+   *     return true;
+   *   }
+   * });
+   * `‍``
    **/
-  removePostMenuButton(name) {
-    removeButton(name);
+  removePostMenuButton(name, callback) {
+    removeButton(name, callback);
   }
 
   /**
diff --git a/app/assets/javascripts/discourse/app/widgets/post-menu.js b/app/assets/javascripts/discourse/app/widgets/post-menu.js
index fcbb426..63c76f0 100644
--- a/app/assets/javascripts/discourse/app/widgets/post-menu.js
+++ b/app/assets/javascripts/discourse/app/widgets/post-menu.js
@@ -10,27 +10,27 @@ const LIKE_ACTION = 2;
 const VIBRATE_DURATION = 5;
 
 const _builders = {};
-const _extraButtons = {};
+let _extraButtons = {};
 export let apiExtraButtons = {};
+let _buttonsToRemove = {};
 
 export function addButton(name, builder) {
   _extraButtons[name] = builder;
 }
 
 export function resetPostMenuExtraButtons() {
-  Object.keys(apiExtraButtons).forEach((button) => {
-    removeButton(button);
-  });
-
+  _buttonsToRemove = {};
   apiExtraButtons = {};
+  _extraButtons = {};
 }
 
-export function removeButton(name) {
-  if (_extraButtons[name]) {
-    delete _extraButtons[name];
-  }
-  if (_builders[name]) {
-    delete _builders[name];
+export function removeButton(name, callback) {
+  if (callback) {
+    _buttonsToRemove[name] = callback;
+  } else {
+    _buttonsToRemove[name] = () => {
+      return true;
+    };
   }
 }
 
@@ -40,8 +40,22 @@ function registerButton(name, builder) {
 
 export function buildButton(name, widget) {
   let { attrs, state, siteSettings, settings, currentUser } = widget;
+
+  let shouldAddButton = true;
+
+  if (_buttonsToRemove[name]) {
+    shouldAddButton = !_buttonsToRemove[name](
+      attrs,
+      state,
+      siteSettings,
+      settings,
+      currentUser
+    );
+  }
+
   let builder = _builders[name];
-  if (builder) {
+
+  if (shouldAddButton && builder) {
     let button = builder(attrs, state, siteSettings, settings, currentUser);
     if (button && !button.id) {
       button.id = name;
@@ -498,7 +512,19 @@ export default createWidget("post-menu", {
     }
 
     Object.values(_extraButtons).forEach((builder) => {
-      if (builder) {
+      let shouldAddButton = true;
+
+      if (_buttonsToRemove[name]) {
+        shouldAddButton = !_buttonsToRemove[name](
+          attrs,
+          this.state,
+          this.siteSettings,
+          this.settings,
+          this.currentUser
+        );
+      }
+
+      if (shouldAddButton && builder) {
         const buttonAtts = builder(
           attrs,
           this.state,
diff --git a/app/assets/javascripts/discourse/tests/integration/widgets/post-menu-test.js b/app/assets/javascripts/discourse/tests/integration/widgets/post-menu-test.js
index 1458fa9..3cd9961 100644
--- a/app/assets/javascripts/discourse/tests/integration/widgets/post-menu-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/widgets/post-menu-test.js
@@ -7,18 +7,23 @@ import {
   exists,
 } from "discourse/tests/helpers/qunit-helpers";
 import hbs from "htmlbars-inline-precompile";
+import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
 import { withPluginApi } from "discourse/lib/plugin-api";
 
 discourseModule(
   "Integration | Component | Widget | post-menu",
   function (hooks) {
+    hooks.afterEach(() => {
+      resetPostMenuExtraButtons();
+    });
+
     setupRenderingTest(hooks);
 
     componentTest("add extra button", {
       template: hbs`{{mount-widget widget="post-menu" args=args}}`,
       beforeEach() {
         this.set("args", {});
-        withPluginApi("0.8", (api) => {
+        withPluginApi("0.14.0", (api) => {
           api.addPostMenuButton("coffee", () => {
             return {
               action: "drinkCoffee",
@@ -30,6 +35,7 @@ discourseModule(
           });
         });
       },
+
       async test(assert) {
         assert.strictEqual(
           count(".actions .extra-buttons .hot-coffee"),
@@ -39,19 +45,54 @@ discourseModule(
       },
     });
 
-    componentTest("remove extra button", {
+    componentTest("removes button based on callback", {
       template: hbs`{{mount-widget widget="post-menu" args=args}}`,
+
       beforeEach() {
-        this.set("args", {});
-        withPluginApi("0.8", (api) => {
-          api.removePostMenuButton("coffee");
+        this.set("args", { canCreatePost: true, canRemoveReply: true });
+
+        withPluginApi("0.14.0", (api) => {
+          api.removePostMenuButton("reply", (attrs) => {
+            return attrs.canRemoveReply;
+          });
         });
       },
+
       async test(assert) {
-        assert.ok(
-          !exists(".actions .extra-buttons .hot-coffee"),
-          "It doesn't removes coffee button"
-        );
+        assert.ok(!exists(".actions .reply"), "it removes reply button");
+      },
+    });
+
+    componentTest("does not remove butto", {
+      template: hbs`{{mount-widget widget="post-menu" args=args}}`,
+
+      beforeEach() {
+        this.set("args", { canCreatePost: true, canRemoveReply: false });
+
+        withPluginApi("0.14.0", (api) => {
+          api.removePostMenuButton("reply", (attrs) => {
+            return attrs.canRemoveReply;
+          });
+        });
+      },
+
+      async test(assert) {
+        assert.ok(exists(".actions .reply"), "it does not remove reply button");
+      },
+    });
+
+    componentTest("removes button", {
+      template: hbs`{{mount-widget widget="post-menu" args=args}}`,
+      beforeEach() {
+        this.set("args", { canCreatePost: true });
+
+        withPluginApi("0.14.0", (api) => {
+          api.removePostMenuButton("reply");
+        });
+      },
+
+      async test(assert) {
+        assert.ok(!exists(".actions .reply"), "it removes reply button");
       },
     });
   }

GitHub sha: 057ef55684b8712966d0d4c6eb19f383b5a22ffd

This commit appears in #15061 which was approved by lis2. It was merged by tgxworld.