소스 검색

Move MUC invite action to the participants dropdown

JC Brand 11 달 전
부모
커밋
8f5a295c80

+ 0 - 22
src/plugins/muc-views/heading.js

@@ -1,10 +1,8 @@
 import './modals/config.js';
 import './modals/config.js';
 import './modals/muc-details.js';
 import './modals/muc-details.js';
-import './modals/muc-invite.js';
 import './modals/nickname.js';
 import './modals/nickname.js';
 import tplMUCHead from './templates/muc-head.js';
 import tplMUCHead from './templates/muc-head.js';
 import { CustomElement } from 'shared/components/element.js';
 import { CustomElement } from 'shared/components/element.js';
-import { Model } from '@converse/skeletor';
 import { __ } from 'i18n';
 import { __ } from 'i18n';
 import { _converse, api, converse } from "@converse/headless";
 import { _converse, api, converse } from "@converse/headless";
 import { destroyMUC, showModeratorToolsModal } from './utils.js';
 import { destroyMUC, showModeratorToolsModal } from './utils.js';
@@ -28,7 +26,6 @@ export default class MUCHeading extends CustomElement {
         this.listenTo(this.user_settings, 'change:mucs_with_hidden_subject', () => this.requestUpdate());
         this.listenTo(this.user_settings, 'change:mucs_with_hidden_subject', () => this.requestUpdate());
 
 
         await this.model.initialized;
         await this.model.initialized;
-        this.listenTo(this.model.features, 'change:open', () => this.requestUpdate());
         this.model.occupants.forEach(o => this.onOccupantAdded(o));
         this.model.occupants.forEach(o => this.onOccupantAdded(o));
         this.listenTo(this.model.occupants, 'add', this.onOccupantAdded);
         this.listenTo(this.model.occupants, 'add', this.onOccupantAdded);
         this.listenTo(this.model.occupants, 'change:affiliation', this.onOccupantAffiliationChanged);
         this.listenTo(this.model.occupants, 'change:affiliation', this.onOccupantAffiliationChanged);
@@ -67,14 +64,6 @@ export default class MUCHeading extends CustomElement {
         api.modal.show('converse-muc-details-modal', { model: this.model }, ev);
         api.modal.show('converse-muc-details-modal', { model: this.model }, ev);
     }
     }
 
 
-    /**
-     * @param {Event} ev
-     */
-    showInviteModal (ev) {
-        ev.preventDefault();
-        api.modal.show('converse-muc-invite-modal', { model: new Model(), 'chatroomview': this }, ev);
-    }
-
     /**
     /**
      * @param {Event} ev
      * @param {Event} ev
      */
      */
@@ -153,17 +142,6 @@ export default class MUCHeading extends CustomElement {
             'name': 'nickname'
             'name': 'nickname'
         });
         });
 
 
-        if (this.model.invitesAllowed()) {
-            buttons.push({
-                'i18n_text': __('Invite'),
-                'i18n_title': __('Invite someone to join this groupchat'),
-                'handler': ev => this.showInviteModal(ev),
-                'a_class': 'open-invite-modal',
-                'icon_class': 'fa-user-plus',
-                'name': 'invite'
-            });
-        }
-
         const subject = this.model.get('subject');
         const subject = this.model.get('subject');
         if (subject && subject.text) {
         if (subject && subject.text) {
             buttons.push({
             buttons.push({

+ 6 - 3
src/plugins/muc-views/modals/muc-invite.js

@@ -10,7 +10,7 @@ export default class MUCInviteModal extends BaseModal {
     constructor (options) {
     constructor (options) {
         super(options);
         super(options);
         this.id = 'converse-muc-invite-modal';
         this.id = 'converse-muc-invite-modal';
-        this.chatroomview = options.chatroomview;
+        this.muc = options.muc;
     }
     }
 
 
     initialize () {
     initialize () {
@@ -30,15 +30,18 @@ export default class MUCInviteModal extends BaseModal {
         return _converse.state.roster.map((i) => ({ label: i.getDisplayName(), value: i.get('jid') }));
         return _converse.state.roster.map((i) => ({ label: i.getDisplayName(), value: i.get('jid') }));
     }
     }
 
 
+    /**
+     * @param {Event} ev
+     */
     submitInviteForm (ev) {
     submitInviteForm (ev) {
         ev.preventDefault();
         ev.preventDefault();
         // TODO: Add support for sending an invite to multiple JIDs
         // TODO: Add support for sending an invite to multiple JIDs
-        const data = new FormData(ev.target);
+        const data = new FormData(/** @type {HTMLFormElement} */(ev.target));
         const jid = /** @type {string} */ (data.get('invitee_jids'))?.trim();
         const jid = /** @type {string} */ (data.get('invitee_jids'))?.trim();
         const reason = data.get('reason');
         const reason = data.get('reason');
         if (u.isValidJID(jid)) {
         if (u.isValidJID(jid)) {
             // TODO: Create and use API here
             // TODO: Create and use API here
-            this.chatroomview.model.directInvite(jid, reason);
+            this.muc.directInvite(jid, reason);
             this.modal.hide();
             this.modal.hide();
         } else {
         } else {
             this.model.set({ 'invalid_invite_jid': true });
             this.model.set({ 'invalid_invite_jid': true });

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

@@ -1,8 +1,10 @@
 import debounce from 'lodash-es/debounce.js';
 import debounce from 'lodash-es/debounce.js';
+import { Model } from '@converse/skeletor';
 import { _converse, api, u, RosterFilter } from "@converse/headless";
 import { _converse, api, u, RosterFilter } from "@converse/headless";
-import 'shared/autocomplete/index.js';
 import { CustomElement } from 'shared/components/element.js';
 import { CustomElement } from 'shared/components/element.js';
 import tplMUCSidebar from "./templates/muc-sidebar.js";
 import tplMUCSidebar from "./templates/muc-sidebar.js";
+import './modals/muc-invite.js';
+import 'shared/autocomplete/index.js';
 
 
 import 'shared/styles/status.scss';
 import 'shared/styles/status.scss';
 import './styles/muc-occupants.scss';
 import './styles/muc-occupants.scss';
@@ -44,6 +46,7 @@ export default class MUCSidebar extends CustomElement {
         this.listenTo(this.model.occupants, 'sort', debouncedRequestUpdate);
         this.listenTo(this.model.occupants, 'sort', debouncedRequestUpdate);
         this.listenTo(this.model.occupants, 'vcard:change', debouncedRequestUpdate);
         this.listenTo(this.model.occupants, 'vcard:change', debouncedRequestUpdate);
         this.listenTo(this.model.occupants, 'vcard:add', debouncedRequestUpdate);
         this.listenTo(this.model.occupants, 'vcard:add', debouncedRequestUpdate);
+        this.listenTo(this.model.features, 'change:open', () => this.requestUpdate());
 
 
         this.model.initialized.then(() => this.requestUpdate());
         this.model.initialized.then(() => this.requestUpdate());
     }
     }
@@ -58,6 +61,14 @@ export default class MUCSidebar extends CustomElement {
         return tpl;
         return tpl;
     }
     }
 
 
+    /**
+     * @param {MouseEvent} ev
+     */
+    showInviteModal (ev) {
+        ev.preventDefault();
+        api.modal.show('converse-muc-invite-modal', { model: new Model(), muc: this.model }, ev);
+    }
+
     /** @param {MouseEvent} ev */
     /** @param {MouseEvent} ev */
     toggleFilter (ev) {
     toggleFilter (ev) {
         ev?.preventDefault?.();
         ev?.preventDefault?.();

+ 60 - 38
src/plugins/muc-views/templates/muc-sidebar.js

@@ -44,61 +44,83 @@ function shouldShowOccupant (el, occ, o) {
  */
  */
 export default (el, o) => {
 export default (el, o) => {
     const i18n_participants = el.model.occupants === 1 ? __('Participant') : __('Participants');
     const i18n_participants = el.model.occupants === 1 ? __('Participant') : __('Participants');
-    const i18n_close = __('Hide sidebar');
+    const i18n_close = __('Hide');
     const i18n_show_filter = __('Show filter');
     const i18n_show_filter = __('Show filter');
     const i18n_hide_filter = __('Hide filter');
     const i18n_hide_filter = __('Hide filter');
     const is_filter_visible = el.model.get('filter_visible');
     const is_filter_visible = el.model.get('filter_visible');
+    const i18n_invite = __('Invite someone')
+    const i18n_invite_title = __('Invite someone to join this groupchat')
 
 
     const btns = /** @type {TemplateResult[]} */ [];
     const btns = /** @type {TemplateResult[]} */ [];
-    if (el.model.occupants?.length < 6) {
-        // We don't show the filter
-        btns.push(
-            html` <i class="hide-occupants" @click=${(/** @type {MouseEvent} */ev) => el.closeSidebar(ev)}>
-                <converse-icon class="fa fa-times" size="1em"></converse-icon>
-            </i>`
-        );
-    } else {
+
+    if (el.model.invitesAllowed()) {
         btns.push(html`
         btns.push(html`
-            <a href="#" class="dropdown-item" @click=${(/** @type {MouseEvent} */ev) => el.closeSidebar(ev)}>
-                <converse-icon size="1em" class="fa fa-times"></converse-icon>
-                ${i18n_close}
+            <a href="#"
+               class="dropdown-item open-invite-modal"
+               title="${i18n_invite_title}"
+               @click=${(/** @type {MouseEvent} */ev) => el.showInviteModal(ev)}>
+                <converse-icon size="1em" class="fa fa-user-plus"></converse-icon>
+                ${i18n_invite}
             </a>
             </a>
         `);
         `);
+    }
+
+    if (el.model.occupants.length > 5) {
         btns.push(html`
         btns.push(html`
-            <a href="#" class="dropdown-item toggle-filter" @click=${(/** @type {MouseEvent} */ev) => el.toggleFilter(ev)}>
+            <a href="#"
+               class="dropdown-item toggle-filter"
+               @click=${(/** @type {MouseEvent} */ev) => el.toggleFilter(ev)}>
                 <converse-icon size="1em" class="fa fa-filter"></converse-icon>
                 <converse-icon size="1em" class="fa fa-filter"></converse-icon>
                 ${is_filter_visible ? i18n_hide_filter : i18n_show_filter}
                 ${is_filter_visible ? i18n_hide_filter : i18n_show_filter}
             </a>
             </a>
         `);
         `);
     }
     }
 
 
+    if (btns.length) {
+        btns.push(html`
+            <a href="#" class="dropdown-item" @click=${(/** @type {MouseEvent} */ev) => el.closeSidebar(ev)}>
+                <converse-icon size="1em" class="fa fa-times"></converse-icon>
+                ${i18n_close}
+            </a>
+        `);
+    } else {
+        // Only a single button is shown, not a dropdown.
+        btns.push(
+            html` <i class="hide-occupants" @click=${(/** @type {MouseEvent} */ev) => el.closeSidebar(ev)}>
+                <converse-icon class="fa fa-times" size="1em"></converse-icon>
+            </i>`
+        );
+    }
+
     return html`
     return html`
-        <div class="occupants-header">
-            <div class="occupants-header--title">
-                <span class="occupants-heading">${el.model.occupants.length} ${i18n_participants}</span>
-                ${btns.length === 1
-                    ? btns[0]
-                        : html`<converse-dropdown
-                            class="chatbox-btn btn-group dropstart"
-                            .items=${btns}></converse-dropdown>`}
+        <div class="dragresize-occupants-left">&nbsp;</div>
+        <div class="occupants">
+            <div class="occupants-header">
+                <div class="occupants-header--title">
+                    <span class="occupants-heading">${el.model.occupants.length} ${i18n_participants}</span>
+                    ${btns.length === 1
+                        ? btns[0]
+                            : html`<converse-dropdown
+                                class="chatbox-btn btn-group dropstart"
+                                .items=${btns}></converse-dropdown>`}
+                </div>
             </div>
             </div>
+            <ul class="occupant-list">
+                ${is_filter_visible
+                    ? html` <converse-list-filter
+                        @update=${() => el.requestUpdate()}
+                        .promise=${el.model.initialized}
+                        .items=${el.model.occupants}
+                        .template=${tplOccupantsFilter}
+                        .model=${el.filter}
+                    ></converse-list-filter>`
+                    : ''}
+                ${repeat(
+                    el.model.occupants.models,
+                    (occ) => occ.get('jid'),
+                    (occ) => shouldShowOccupant(el, occ, o)
+                )}
+            </ul>
         </div>
         </div>
-        <div class="dragresize dragresize-occupants-left"></div>
-        <ul class="occupant-list">
-            ${is_filter_visible
-                ? html` <converse-list-filter
-                      @update=${() => el.requestUpdate()}
-                      .promise=${el.model.initialized}
-                      .items=${el.model.occupants}
-                      .template=${tplOccupantsFilter}
-                      .model=${el.filter}
-                  ></converse-list-filter>`
-                : ''}
-            ${repeat(
-                el.model.occupants.models,
-                (occ) => occ.get('jid'),
-                (occ) => shouldShowOccupant(el, occ, o)
-            )}
-        </ul>
     `;
     `;
 };
 };

+ 0 - 4
src/types/plugins/muc-views/heading.d.ts

@@ -18,10 +18,6 @@ export default class MUCHeading extends CustomElement {
      * @param {Event} ev
      * @param {Event} ev
      */
      */
     showRoomDetailsModal(ev: Event): void;
     showRoomDetailsModal(ev: Event): void;
-    /**
-     * @param {Event} ev
-     */
-    showInviteModal(ev: Event): void;
     /**
     /**
      * @param {Event} ev
      * @param {Event} ev
      */
      */

+ 5 - 2
src/types/plugins/muc-views/modals/muc-invite.d.ts

@@ -1,10 +1,13 @@
 export default class MUCInviteModal extends BaseModal {
 export default class MUCInviteModal extends BaseModal {
     constructor(options: any);
     constructor(options: any);
-    chatroomview: any;
+    muc: any;
     renderModal(): import("lit").TemplateResult<1>;
     renderModal(): import("lit").TemplateResult<1>;
     getModalTitle(): any;
     getModalTitle(): any;
     getAutoCompleteList(): any;
     getAutoCompleteList(): any;
-    submitInviteForm(ev: any): void;
+    /**
+     * @param {Event} ev
+     */
+    submitInviteForm(ev: Event): void;
 }
 }
 import BaseModal from "plugins/modal/modal.js";
 import BaseModal from "plugins/modal/modal.js";
 //# sourceMappingURL=muc-invite.d.ts.map
 //# sourceMappingURL=muc-invite.d.ts.map

+ 4 - 0
src/types/plugins/muc-views/sidebar.d.ts

@@ -9,6 +9,10 @@ export default class MUCSidebar extends CustomElement {
     filter: RosterFilter;
     filter: RosterFilter;
     model: any;
     model: any;
     render(): import("lit").TemplateResult<1>;
     render(): import("lit").TemplateResult<1>;
+    /**
+     * @param {MouseEvent} ev
+     */
+    showInviteModal(ev: MouseEvent): void;
     /** @param {MouseEvent} ev */
     /** @param {MouseEvent} ev */
     toggleFilter(ev: MouseEvent): void;
     toggleFilter(ev: MouseEvent): void;
     /** @param {MouseEvent} ev */
     /** @param {MouseEvent} ev */