瀏覽代碼

New "getOccupantActionButtons" hook, so that plugins can add actions on MUC occupants.

John Livingston 11 月之前
父節點
當前提交
8c722c0450

+ 1 - 0
CHANGES.md

@@ -35,6 +35,7 @@
 - Upgrade to Bootstrap 5
 - Add a new theme 'Cyberpunk' and remove the old 'Concord' theme.
 - Improved accessibility.
+- New "getOccupantActionButtons" hook, so that plugins can add actions on MUC occupants.
 
 ### Breaking changes:
 

+ 1 - 1
src/plugins/muc-views/sidebar.js

@@ -55,7 +55,7 @@ export default class MUCSidebar extends CustomElement {
         const tpl = tplMUCSidebar(this, Object.assign(
             this.model.toJSON(), {
                 'occupants': [...this.model.occupants.models],
-                'onOccupantClicked': ev => this.onOccupantClicked(ev),
+                'onOccupantClicked': ev => this.onOccupantClicked(ev)
             }
         ));
         return tpl;

+ 4 - 1
src/plugins/muc-views/styles/muc-occupants.scss

@@ -108,8 +108,9 @@
 
                             .occupant-nick-badge {
                                 display: flex;
-                                justify-content: space-between;
+                                justify-content: flex-start;
                                 flex-wrap: wrap;
+                                align-items: center;
 
                                 .occupant-badges {
                                     display: flex;
@@ -117,6 +118,8 @@
                                     flex-wrap: wrap;
                                     flex-direction: row;
 
+                                    margin-left: auto; // this tricks align the item to the right.
+
                                     span {
                                         height: 1.6em;
                                         margin-right: 0.25rem;

+ 32 - 0
src/plugins/muc-views/templates/occupant.js

@@ -1,9 +1,11 @@
 /**
  * @typedef {import('@converse/headless').MUCOccupant} MUCOccupant
  */
+import { api } from '@converse/headless';
 import { PRETTY_CHAT_STATUS } from '../constants.js';
 import { __ } from 'i18n';
 import { html } from "lit";
+import { until } from 'lit/directives/until.js';
 import { showOccupantModal } from '../utils.js';
 import { getAuthorStyle } from 'utils/color.js';
 
@@ -29,6 +31,33 @@ const occupant_title = /** @param {MUCOccupant} o */(o) => {
     }
 }
 
+/**
+ * @param {MUCOccupant} o
+ */
+async function tplActionButtons (o) {
+    const buttons = await api.hook('getOccupantActionButtons', o, []);
+    if (!buttons?.length) { return '' }
+
+    const items = buttons.map(b => {
+        return html`
+        <button class="dropdown-item ${b.button_class}" @click=${b.handler}>
+            <converse-icon
+                class="${b.icon_class}"
+                color="var(--inverse-link-color)"
+                size="1em"
+            ></converse-icon>&nbsp;${b.i18n_text}
+        </button>`
+    });
+
+    if (!items.length) {
+        return ''
+    }
+
+    return html`<converse-dropdown
+        class="btn btn--transparent btn--standalone dropdown-toggle dropdown-toggle--no-caret"
+        .items=${items}
+    ></converse-dropdown>`;
+}
 
 /**
  * @param {MUCOccupant} o
@@ -80,6 +109,9 @@ export default (o, chat) => {
                           title="${occupant_title(o)}"
                           @click=${chat.onOccupantClicked}
                           style="${getAuthorStyle(o)}">${o.getDisplayName()}</span>
+                    ${
+                        until(tplActionButtons(o))
+                    }
                     <span class="occupant-badges">
                         ${ (affiliation === "owner") ? html`<span class="badge badge-groupchat">${i18n_owner}</span>` : '' }
                         ${ (affiliation === "admin") ? html`<span class="badge badge-info">${i18n_admin}</span>` : '' }