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.
This commit is contained in:
Alan Guo Xiang Tan 2021-11-24 13:26:52 +08:00 committed by GitHub
parent 44be79f095
commit 057ef55684
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 25 deletions

View File

@ -94,7 +94,7 @@ import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
import { downloadCalendar } from "discourse/lib/download-calendar"; import { downloadCalendar } from "discourse/lib/download-calendar";
// If you add any methods to the API ensure you bump up this number // 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. // This helper prevents us from applying the same `modifyClass` over and over in test mode.
function canModify(klass, type, resolverName, changes) { function canModify(klass, type, resolverName, changes) {
@ -490,9 +490,17 @@ class PluginApi {
* ``` * ```
* api.removePostMenuButton('like'); * api.removePostMenuButton('like');
* ``` * ```
*
* ```
* api.removePostMenuButton('like', (attrs, state, siteSettings, settings, currentUser) => {
* if (attrs.post_number === 1) {
* return true;
* }
* });
* ```
**/ **/
removePostMenuButton(name) { removePostMenuButton(name, callback) {
removeButton(name); removeButton(name, callback);
} }
/** /**

View File

@ -10,27 +10,27 @@ const LIKE_ACTION = 2;
const VIBRATE_DURATION = 5; const VIBRATE_DURATION = 5;
const _builders = {}; const _builders = {};
const _extraButtons = {}; let _extraButtons = {};
export let apiExtraButtons = {}; export let apiExtraButtons = {};
let _buttonsToRemove = {};
export function addButton(name, builder) { export function addButton(name, builder) {
_extraButtons[name] = builder; _extraButtons[name] = builder;
} }
export function resetPostMenuExtraButtons() { export function resetPostMenuExtraButtons() {
Object.keys(apiExtraButtons).forEach((button) => { _buttonsToRemove = {};
removeButton(button);
});
apiExtraButtons = {}; apiExtraButtons = {};
_extraButtons = {};
} }
export function removeButton(name) { export function removeButton(name, callback) {
if (_extraButtons[name]) { if (callback) {
delete _extraButtons[name]; _buttonsToRemove[name] = callback;
} } else {
if (_builders[name]) { _buttonsToRemove[name] = () => {
delete _builders[name]; return true;
};
} }
} }
@ -40,8 +40,22 @@ function registerButton(name, builder) {
export function buildButton(name, widget) { export function buildButton(name, widget) {
let { attrs, state, siteSettings, settings, currentUser } = 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]; let builder = _builders[name];
if (builder) {
if (shouldAddButton && builder) {
let button = builder(attrs, state, siteSettings, settings, currentUser); let button = builder(attrs, state, siteSettings, settings, currentUser);
if (button && !button.id) { if (button && !button.id) {
button.id = name; button.id = name;
@ -498,7 +512,19 @@ export default createWidget("post-menu", {
} }
Object.values(_extraButtons).forEach((builder) => { 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( const buttonAtts = builder(
attrs, attrs,
this.state, this.state,

View File

@ -7,18 +7,23 @@ import {
exists, exists,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
import { withPluginApi } from "discourse/lib/plugin-api"; import { withPluginApi } from "discourse/lib/plugin-api";
discourseModule( discourseModule(
"Integration | Component | Widget | post-menu", "Integration | Component | Widget | post-menu",
function (hooks) { function (hooks) {
hooks.afterEach(() => {
resetPostMenuExtraButtons();
});
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("add extra button", { componentTest("add extra button", {
template: hbs`{{mount-widget widget="post-menu" args=args}}`, template: hbs`{{mount-widget widget="post-menu" args=args}}`,
beforeEach() { beforeEach() {
this.set("args", {}); this.set("args", {});
withPluginApi("0.8", (api) => { withPluginApi("0.14.0", (api) => {
api.addPostMenuButton("coffee", () => { api.addPostMenuButton("coffee", () => {
return { return {
action: "drinkCoffee", action: "drinkCoffee",
@ -30,6 +35,7 @@ discourseModule(
}); });
}); });
}, },
async test(assert) { async test(assert) {
assert.strictEqual( assert.strictEqual(
count(".actions .extra-buttons .hot-coffee"), 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}}`, template: hbs`{{mount-widget widget="post-menu" args=args}}`,
beforeEach() { beforeEach() {
this.set("args", {}); this.set("args", { canCreatePost: true, canRemoveReply: true });
withPluginApi("0.8", (api) => {
api.removePostMenuButton("coffee"); withPluginApi("0.14.0", (api) => {
api.removePostMenuButton("reply", (attrs) => {
return attrs.canRemoveReply;
});
}); });
}, },
async test(assert) { async test(assert) {
assert.ok( assert.ok(!exists(".actions .reply"), "it removes reply button");
!exists(".actions .extra-buttons .hot-coffee"), },
"It doesn't removes coffee 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");
}, },
}); });
} }