Przeglądaj źródła

Fixes #1535

Add option to destroy MUC in the dropdown context menu.
Also add a confirmation dialog.
JC Brand 5 lat temu
rodzic
commit
61e86a3c23
4 zmienionych plików z 56 dodań i 31 usunięć
  1. 2 1
      CHANGES.md
  2. 7 15
      spec/muc.js
  3. 1 1
      src/converse-bookmark-views.js
  4. 46 14
      src/converse-muc-views.js

+ 2 - 1
CHANGES.md

@@ -8,9 +8,10 @@
 - Start using [lit-html](https://lit-html.polymer-project.org/) instead of lodash for templating.
 - Bugfix. Handle stanza that clears the MUC subject
 - #1313: Stylistic improvements to the send button
+- #1535: Add option to destroy a MUC
 - #1793: Send button doesn't appear in Firefox in 1:1 chats
-- #1822: Don't log error if user has no bookmarks
 - #1820: Set focus on jid field after controlbox is loaded
+- #1822: Don't log error if user has no bookmarks
 - #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy)
     and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint)
 - #1826: A user can now add himself as a contact

+ 7 - 15
spec/muc.js

@@ -3966,17 +3966,15 @@
                 const muc_jid = 'lounge@montague.lit';
                 await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
                 const view = _converse.api.chatviews.get(muc_jid);
-                let sent_IQ, IQ_id;
-                const sendIQ = _converse.connection.sendIQ;
-                spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
-                    sent_IQ = iq;
-                    IQ_id = sendIQ.bind(this)(iq, callback, errback);
-                });
+                spyOn(_converse.api, 'confirm').and.callFake(() => Promise.resolve(true));
                 const textarea = view.el.querySelector('.chat-textarea');
                 textarea.value = '/destroy bored';
                 view.onFormSubmitted(new Event('submit'));
-                expect(sent_IQ.toLocaleString()).toBe(
-                    `<iq id="${IQ_id}" to="lounge@montague.lit" type="set" xmlns="jabber:client">`+
+
+                const sent_IQs = _converse.connection.IQ_stanzas;
+                const sent_IQ = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector('destroy')).pop());
+                expect(Strophe.serialize(sent_IQ)).toBe(
+                    `<iq id="${sent_IQ.getAttribute('id')}" to="lounge@montague.lit" type="set" xmlns="jabber:client">`+
                         `<query xmlns="http://jabber.org/protocol/muc#owner">`+
                             `<destroy>`+
                                 `<reason>`+
@@ -3986,15 +3984,9 @@
                         `</query>`+
                     `</iq>`);
 
-                /* <iq from="lounge@montague.lit"
-                 *  id="${IQ_id}"
-                 *  to="romeo@montague.lit/orchard"
-                 *  type="result"
-                 *  xmlns="jabber:client"/>
-                */
                 const result_stanza = $iq({
                     'type': 'result',
-                    'id': IQ_id,
+                    'id': sent_IQ.getAttribute('id'),
                     'from': view.model.get('jid'),
                     'to': _converse.connection.jid
                 });

+ 1 - 1
src/converse-bookmark-views.js

@@ -50,7 +50,7 @@ converse.plugins.add('converse-bookmark-views', {
                         'name': 'bookmark'
                     }
                     const names = buttons.map(t => t.name);
-                    const idx = names.indexOf('configure');
+                    const idx = names.indexOf('details');
                     const data_promise = supported.then(s => s ? data : '');
                     return idx > -1 ? [...buttons.slice(0, idx), data_promise, ...buttons.slice(idx)] : [data_promise, ...buttons];
                 }

+ 46 - 14
src/converse-muc-views.js

@@ -1112,16 +1112,6 @@ converse.plugins.add('converse-muc-views', {
                     'icon_class': 'fa-info-circle',
                     'name': 'details'
                 }];
-                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'
-                    });
-                }
                 if (this.model.getOwnAffiliation() === 'owner') {
                     buttons.push({
                         'i18n_text': __('Configure'),
@@ -1133,7 +1123,44 @@ converse.plugins.add('converse-muc-views', {
                     });
                 }
 
-                if (this.model.get('subject')) {
+                const conn_status = this.model.session.get('connection_status');
+                if (conn_status === converse.ROOMSTATUS.ENTERED) {
+                    const allowed_commands = this.getAllowedCommands();
+                    if (allowed_commands.includes('modtools')) {
+                        buttons.push({
+                            'i18n_text': __('Moderate'),
+                            'i18n_title': __('Moderate this groupchat'),
+                            'handler': () => this.showModeratorToolsModal(),
+                            'a_class': 'moderate-chatroom-button',
+                            'icon_class': 'fa-user-cog',
+                            'name': 'moderate'
+                        });
+                    }
+                    if (allowed_commands.includes('destroy')) {
+                        buttons.push({
+                            'i18n_text': __('Destroy'),
+                            'i18n_title': __('Remove this groupchat'),
+                            'handler': ev => this.destroy(ev),
+                            'a_class': 'destroy-chatroom-button',
+                            'icon_class': 'fa-trash',
+                            'name': 'destroy'
+                        });
+                    }
+                }
+
+                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');
+                if (subject && subject.text) {
                     buttons.push({
                         'i18n_text': this.model.get('subject_hidden') ? __('Show topic') : __('Hide topic'),
                         'i18n_title': this.model.get('subject_hidden') ?
@@ -1466,6 +1493,13 @@ converse.plugins.add('converse-muc-views', {
                 }
             },
 
+            async destroy (reason, new_jid) {
+                const message = [__('Are you sure you want to destroy this groupchat?')];
+                if (await _converse.api.confirm(__('Confirm'), message)) {
+                    return this.model.sendDestroyIQ(reason, new_jid).then(() => this.close())
+                }
+            },
+
             parseMessageForCommands (text) {
                 if (_converse.muc_disable_slash_commands && !Array.isArray(_converse.muc_disable_slash_commands)) {
                     return _converse.ChatBoxView.prototype.parseMessageForCommands.apply(this, arguments);
@@ -1510,9 +1544,7 @@ converse.plugins.add('converse-muc-views', {
                         if (!this.verifyAffiliations(['owner'])) {
                             break;
                         }
-                        this.model.sendDestroyIQ(args)
-                            .then(() => this.close())
-                            .catch(e => this.onCommandError(e));
+                        this.destroy(args).catch(e => this.onCommandError(e));
                         break;
                     }
                     case 'help': {