diff --git a/css/converse.css b/css/converse.css index 250400b17..79fed49c3 100644 --- a/css/converse.css +++ b/css/converse.css @@ -11683,8 +11683,9 @@ body.converse-fullscreen { #conversejs.converse-embedded .chatroom .muc-bottom-panel, #conversejs .chatroom .muc-bottom-panel { border-top: var(--message-input-border-top); - height: 4em; - padding: 1em; + height: 3em; + padding: 0.5em; + text-align: center; font-size: var(--font-size-small); background-color: var(--chatroom-head-color); color: white; } diff --git a/dist/converse.js b/dist/converse.js index de3a5c3f2..79a4c6923 100644 --- a/dist/converse.js +++ b/dist/converse.js @@ -53849,6 +53849,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this); this.model.on('destroy', this.hide, this); this.model.on('show', this.show, this); + this.model.features.on('change:moderated', this.renderBottomPanel, this); this.model.occupants.on('add', this.onOccupantAdded, this); this.model.occupants.on('remove', this.onOccupantRemoved, this); this.model.occupants.on('change:show', this.showJoinOrLeaveNotification, this); @@ -53912,7 +53913,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins renderBottomPanel() { const container = this.el.querySelector('.bottom-panel'); - if (this.model.get('role') === 'visitor') { + if (this.model.features.get('moderated') && this.model.get('role') === 'visitor') { container.innerHTML = templates_chatroom_bottom_panel_html__WEBPACK_IMPORTED_MODULE_10___default()({ '__': __ }); @@ -62747,8 +62748,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha } else { // An error message without id likely means that we // sent a message without id (which shouldn't happen). - _converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR); - _converse.log(message, Strophe.LogLevel.ERROR); } diff --git a/sass/_chatrooms.scss b/sass/_chatrooms.scss index 4b5ee6fab..a71c53475 100644 --- a/sass/_chatrooms.scss +++ b/sass/_chatrooms.scss @@ -308,8 +308,9 @@ .muc-bottom-panel { border-top: var(--message-input-border-top); - height: 4em; - padding: 1em; + height: 3em; + padding: 0.5em; + text-align: center; font-size: var(--font-size-small); background-color: var(--chatroom-head-color); color: white; diff --git a/spec/muc.js b/spec/muc.js index 92b9b1817..fb793b1c5 100644 --- a/spec/muc.js +++ b/spec/muc.js @@ -167,7 +167,7 @@ chatroomview = _converse.chatboxviews.get('room@conference.example.org'); // We pretend this is a new room, so no disco info is returned. - var features_stanza = $iq({ + const features_stanza = $iq({ from: 'room@conference.example.org', 'id': IQ_id, 'to': 'dummy@localhost/desktop', @@ -184,7 +184,7 @@ * * */ - var presence = $pres({ + const presence = $pres({ from:'room@conference.example.org/some1', to:'dummy@localhost/pda' }) @@ -4667,8 +4667,16 @@ null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, async function (done, _converse) { - await test_utils.openAndEnterChatRoom(_converse, 'trollbox', 'localhost', 'troll'); + const features = [ + 'http://jabber.org/protocol/muc', + 'jabber:iq:register', + Strophe.NS.SID, + 'muc_moderated', + ] + await test_utils.openAndEnterChatRoom(_converse, 'trollbox', 'localhost', 'troll', features); const view = _converse.chatboxviews.get('trollbox@localhost'); + expect(_.isNull(view.el.querySelector('.chat-textarea'))).toBe(false); + let stanza = u.toStanza(` `); _converse.connection._dataRecv(test_utils.createRequest(stanza)); + + expect(view.el.querySelector('.chat-textarea')).toBe(null); + let bottom_panel = view.el.querySelector('.muc-bottom-panel'); + expect(bottom_panel.textContent.trim()).toBe("You're not allowed to send messages in this room"); + + // This only applies to moderated rooms, so let's check that + // the textarea becomes visible when the room's + // configuration changes to be non-moderated + view.model.features.set('moderated', false); + expect(view.el.querySelector('.muc-bottom-panel')).toBe(null); + let textarea = view.el.querySelector('.chat-textarea'); + expect(_.isNull(textarea)).toBe(false); + + view.model.features.set('moderated', true); + expect(view.el.querySelector('.chat-textarea')).toBe(null); + bottom_panel = view.el.querySelector('.muc-bottom-panel'); + expect(bottom_panel.textContent.trim()).toBe("You're not allowed to send messages in this room"); + + // Check now that things get restored when the user is given a voice let info_msgs = sizzle('.chat-info', view.el); expect(info_msgs.length).toBe(4); expect(info_msgs[2].textContent).toBe("troll is no longer a moderator"); @@ -4699,6 +4726,13 @@ `); _converse.connection._dataRecv(test_utils.createRequest(stanza)); info_msgs = sizzle('.chat-info', view.el); + + bottom_panel = view.el.querySelector('.muc-bottom-panel'); + expect(bottom_panel).toBe(null); + + textarea = view.el.querySelector('.chat-textarea'); + expect(_.isNull(textarea)).toBe(false); + expect(info_msgs.length).toBe(5); expect(info_msgs[4].textContent).toBe("troll has been given a voice again"); done(); diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index b309ddf73..d23f52328 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -547,6 +547,8 @@ converse.plugins.add('converse-muc-views', { this.model.on('destroy', this.hide, this); this.model.on('show', this.show, this); + this.model.features.on('change:moderated', this.renderBottomPanel, this); + this.model.occupants.on('add', this.onOccupantAdded, this); this.model.occupants.on('remove', this.onOccupantRemoved, this); this.model.occupants.on('change:show', this.showJoinOrLeaveNotification, this); @@ -601,7 +603,7 @@ converse.plugins.add('converse-muc-views', { renderBottomPanel () { const container = this.el.querySelector('.bottom-panel'); - if (this.model.get('role') === 'visitor') { + if (this.model.features.get('moderated') && this.model.get('role') === 'visitor') { container.innerHTML = tpl_chatroom_bottom_panel({'__': __}); } else { if (!container.firstElementChild || !container.querySelector('.sendXMPPMessage')) { diff --git a/src/headless/converse-chatboxes.js b/src/headless/converse-chatboxes.js index 8cc078ef8..49e37ba73 100644 --- a/src/headless/converse-chatboxes.js +++ b/src/headless/converse-chatboxes.js @@ -898,7 +898,6 @@ converse.plugins.add('converse-chatboxes', { } else { // An error message without id likely means that we // sent a message without id (which shouldn't happen). - _converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR); _converse.log(message, Strophe.LogLevel.ERROR); } const attrs = await chatbox.getMessageAttributesFromStanza(message, message); diff --git a/src/headless/dist/converse-headless.js b/src/headless/dist/converse-headless.js index 3736f3a7b..77e513fdc 100644 --- a/src/headless/dist/converse-headless.js +++ b/src/headless/dist/converse-headless.js @@ -41261,8 +41261,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha } else { // An error message without id likely means that we // sent a message without id (which shouldn't happen). - _converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR); - _converse.log(message, Strophe.LogLevel.ERROR); }