diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 6b16d724d7f..e869e47daae 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 fcbb4263b89..63c76f053a3 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 1458fa9cf7a..3cd9961d0d3 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"); }, }); }