From 77781f9a11b499e45a5a5d7fbe73fbe5e17d88ee Mon Sep 17 00:00:00 2001 From: Natalie Tay Date: Wed, 15 Dec 2021 18:09:26 +0800 Subject: [PATCH] FEATURE: Extend plugin API to add multiple poster icons (#15311) --- .../discourse/app/lib/plugin-api.js | 97 ++++++++++++------- docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md | 7 ++ 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 5c9b68eb5f4..f950538b174 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -97,7 +97,7 @@ import { downloadCalendar } from "discourse/lib/download-calendar"; // based on Semantic Versioning 2.0.0. Please up the changelog at // docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version // using the format described at https://keepachangelog.com/en/1.0.0/. -const PLUGIN_API_VERSION = "1.0.0"; +const PLUGIN_API_VERSION = "1.1.0"; // This helper prevents us from applying the same `modifyClass` over and over in test mode. function canModify(klass, type, resolverName, changes) { @@ -331,12 +331,22 @@ class PluginApi { /** * addPosterIcon(callback) * - * This function can be used to add an icon with a link that will be displayed - * beside a poster's name. The `callback` is called with the post's user custom - * fields and post attributes. An icon will be rendered if the callback returns - * an object with the appropriate attributes. + * This function is an alias of addPosterIcons, which the latter has the ability + * to add multiple icons at once. Please refer to `addPosterIcons` for usage examples. + **/ + addPosterIcon(cb) { + this.addPosterIcons(cb); + } + + /** + * addPosterIcons(callback) * - * The returned object can have the following attributes: + * This function can be used to add one, or multiple icons, with a link that will + * be displayed beside a poster's name. The `callback` is called with the post's + * user custom fields and post attributes. One or multiple icons may be rendered + * when the callback returns an array of objects with the appropriate attributes. + * + * The returned object(s) each can have the following attributes: * * icon the font awesome icon to render * emoji an emoji icon to render @@ -346,49 +356,70 @@ class PluginApi { * text (optional) text to display alongside the emoji or icon * * ``` - * api.addPosterIcon((cfs, attrs) => { + * api.addPosterIcons((cfs, attrs) => { * if (cfs.customer) { * return { icon: 'user', className: 'customer', title: 'customer' }; * } * }); * ``` + * or + * * ``` + * api.addPosterIcons((cfs, attrs) => { + * return attrs.customers.map(({name}) => { + * icon: 'user', className: 'customer', title: name + * }) + * }); + * ``` **/ - addPosterIcon(cb) { + addPosterIcons(cb) { const site = this._lookupContainer("site:main"); const loc = site && site.mobileView ? "before" : "after"; decorateWidget(`poster-name:${loc}`, (dec) => { const attrs = dec.attrs; - const result = cb(attrs.userCustomFields || {}, attrs); + let results = cb(attrs.userCustomFields || {}, attrs); - if (result) { - let iconBody; - - if (result.icon) { - iconBody = iconNode(result.icon); - } else if (result.emoji) { - iconBody = result.emoji.split("|").map((name) => { - let widgetAttrs = { name }; - if (result.emojiTitle) { - widgetAttrs.title = true; - } - return dec.attach("emoji", widgetAttrs); - }); + if (results) { + if (!Array.isArray(results)) { + results = [results]; } - if (result.text) { - iconBody = [iconBody, result.text]; - } + return results.map((result) => { + let iconBody; - if (result.url) { - iconBody = dec.h("a", { attributes: { href: result.url } }, iconBody); - } + if (result.icon) { + iconBody = iconNode(result.icon); + } else if (result.emoji) { + iconBody = result.emoji.split("|").map((name) => { + let widgetAttrs = { name }; + if (result.emojiTitle) { + widgetAttrs.title = true; + } + return dec.attach("emoji", widgetAttrs); + }); + } - return dec.h( - "span.poster-icon", - { className: result.className, attributes: { title: result.title } }, - iconBody - ); + if (result.text) { + iconBody = [iconBody, result.text]; + } + + if (result.url) { + iconBody = dec.h( + "a", + { attributes: { href: result.url } }, + iconBody + ); + } + + return dec.h( + "span.poster-icon", + { + className: result.className, + attributes: { title: result.title }, + }, + iconBody + ); + }); } }); } diff --git a/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md b/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md index 7ded201f976..8f0e699a4f3 100644 --- a/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md +++ b/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md @@ -7,6 +7,13 @@ in this file.. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - 2021-12-15 +### Added +- Adds `addPosterIcons`, which allows users to add multiple icons to a poster. The +addition of this function also makes the existing `addPosterIcon` now an alias to this +function. Users may now just use `addPosterIcons` for both one or many icons. This +function allows users to now return many icons depending on an `attrs`. + ## [1.0.0] - 2021-11-25 ### Removed - Removes the `addComposerUploadProcessor` function, which is no longer used in