Pārlūkot izejas kodu

Hide the textarea when a user is muted in a groupchat

JC Brand 6 gadi atpakaļ
vecāks
revīzija
f84c201437

+ 1 - 0
CHANGES.md

@@ -5,6 +5,7 @@
 * Bugfix: Don't set `muc_domain` for roomspanel if `locked_muc_domain` is `true`.
 * Bugfix: Don't set `muc_domain` for roomspanel if `locked_muc_domain` is `true`.
 * Bugfix: Modal auto-closes when you open it for a second time.
 * Bugfix: Modal auto-closes when you open it for a second time.
 * Take roster nickname into consideration when rendering messages and chat headings.
 * Take roster nickname into consideration when rendering messages and chat headings.
+* Hide the textarea when a user is muted in a groupchat.
 
 
 ## 4.2.0 (2019-04-04)
 ## 4.2.0 (2019-04-04)
 
 

+ 8 - 0
css/converse.css

@@ -11680,6 +11680,14 @@ body.converse-fullscreen {
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,
         #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary {
         #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary {
           background-color: var(--chatroom-head-button-color); }
           background-color: var(--chatroom-head-button-color); }
+  #conversejs.converse-embedded .chatroom .muc-bottom-panel,
+  #conversejs .chatroom .muc-bottom-panel {
+    border-top: var(--message-input-border-top);
+    height: 4em;
+    padding: 1em;
+    font-size: var(--font-size-small);
+    background-color: var(--chatroom-head-color);
+    color: white; }
   #conversejs.converse-embedded .chatroom .sendXMPPMessage .suggestion-box__results--above,
   #conversejs.converse-embedded .chatroom .sendXMPPMessage .suggestion-box__results--above,
   #conversejs .chatroom .sendXMPPMessage .suggestion-box__results--above {
   #conversejs .chatroom .sendXMPPMessage .suggestion-box__results--above {
     bottom: 4.5em; }
     bottom: 4.5em; }

+ 118 - 82
dist/converse.js

@@ -49266,7 +49266,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
           placeholder = __('Message');
           placeholder = __('Message');
         }
         }
 
 
-        const form_container = this.el.querySelector('.message-form-container');
+        const form_container = this.el.querySelector('.bottom-panel');
         form_container.innerHTML = templates_chatbox_message_form_html__WEBPACK_IMPORTED_MODULE_9___default()(_.extend(this.model.toJSON(), {
         form_container.innerHTML = templates_chatbox_message_form_html__WEBPACK_IMPORTED_MODULE_9___default()(_.extend(this.model.toJSON(), {
           'hint_value': _.get(this.el.querySelector('.spoiler-hint'), 'value'),
           'hint_value': _.get(this.el.querySelector('.spoiler-hint'), 'value'),
           'label_message': placeholder,
           'label_message': placeholder,
@@ -53254,44 +53254,46 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var templates_chatarea_html__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(templates_chatarea_html__WEBPACK_IMPORTED_MODULE_8__);
 /* harmony import */ var templates_chatarea_html__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(templates_chatarea_html__WEBPACK_IMPORTED_MODULE_8__);
 /* harmony import */ var templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! templates/chatroom.html */ "./src/templates/chatroom.html");
 /* harmony import */ var templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! templates/chatroom.html */ "./src/templates/chatroom.html");
 /* harmony import */ var templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9__);
 /* harmony import */ var templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9__);
-/* harmony import */ var templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! templates/chatroom_destroyed.html */ "./src/templates/chatroom_destroyed.html");
-/* harmony import */ var templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_10__);
-/* harmony import */ var templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! templates/chatroom_details_modal.html */ "./src/templates/chatroom_details_modal.html");
-/* harmony import */ var templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_11__);
-/* harmony import */ var templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! templates/chatroom_disconnect.html */ "./src/templates/chatroom_disconnect.html");
-/* harmony import */ var templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_12__);
-/* harmony import */ var templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! templates/chatroom_features.html */ "./src/templates/chatroom_features.html");
-/* harmony import */ var templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_13__);
-/* harmony import */ var templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! templates/chatroom_form.html */ "./src/templates/chatroom_form.html");
-/* harmony import */ var templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_14__);
-/* harmony import */ var templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! templates/chatroom_head.html */ "./src/templates/chatroom_head.html");
-/* harmony import */ var templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_15__);
-/* harmony import */ var templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! templates/chatroom_invite.html */ "./src/templates/chatroom_invite.html");
-/* harmony import */ var templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_16__);
-/* harmony import */ var templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! templates/chatroom_nickname_form.html */ "./src/templates/chatroom_nickname_form.html");
-/* harmony import */ var templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_17__);
-/* harmony import */ var templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! templates/chatroom_password_form.html */ "./src/templates/chatroom_password_form.html");
-/* harmony import */ var templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_18__);
-/* harmony import */ var templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! templates/chatroom_sidebar.html */ "./src/templates/chatroom_sidebar.html");
-/* harmony import */ var templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_19__);
-/* harmony import */ var templates_info_html__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! templates/info.html */ "./src/templates/info.html");
-/* harmony import */ var templates_info_html__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(templates_info_html__WEBPACK_IMPORTED_MODULE_20__);
-/* harmony import */ var templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! templates/list_chatrooms_modal.html */ "./src/templates/list_chatrooms_modal.html");
-/* harmony import */ var templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_21___default = /*#__PURE__*/__webpack_require__.n(templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_21__);
-/* harmony import */ var templates_occupant_html__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! templates/occupant.html */ "./src/templates/occupant.html");
-/* harmony import */ var templates_occupant_html__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(templates_occupant_html__WEBPACK_IMPORTED_MODULE_22__);
-/* harmony import */ var templates_room_description_html__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! templates/room_description.html */ "./src/templates/room_description.html");
-/* harmony import */ var templates_room_description_html__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(templates_room_description_html__WEBPACK_IMPORTED_MODULE_23__);
-/* harmony import */ var templates_room_item_html__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! templates/room_item.html */ "./src/templates/room_item.html");
-/* harmony import */ var templates_room_item_html__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(templates_room_item_html__WEBPACK_IMPORTED_MODULE_24__);
-/* harmony import */ var templates_room_panel_html__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! templates/room_panel.html */ "./src/templates/room_panel.html");
-/* harmony import */ var templates_room_panel_html__WEBPACK_IMPORTED_MODULE_25___default = /*#__PURE__*/__webpack_require__.n(templates_room_panel_html__WEBPACK_IMPORTED_MODULE_25__);
-/* harmony import */ var templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! templates/rooms_results.html */ "./src/templates/rooms_results.html");
-/* harmony import */ var templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_26__);
-/* harmony import */ var templates_spinner_html__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! templates/spinner.html */ "./src/templates/spinner.html");
-/* harmony import */ var templates_spinner_html__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(templates_spinner_html__WEBPACK_IMPORTED_MODULE_27__);
-/* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js");
-/* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_28___default = /*#__PURE__*/__webpack_require__.n(xss__WEBPACK_IMPORTED_MODULE_28__);
+/* harmony import */ var templates_chatroom_bottom_panel_html__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! templates/chatroom_bottom_panel.html */ "./src/templates/chatroom_bottom_panel.html");
+/* harmony import */ var templates_chatroom_bottom_panel_html__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_bottom_panel_html__WEBPACK_IMPORTED_MODULE_10__);
+/* harmony import */ var templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! templates/chatroom_destroyed.html */ "./src/templates/chatroom_destroyed.html");
+/* harmony import */ var templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_11__);
+/* harmony import */ var templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! templates/chatroom_details_modal.html */ "./src/templates/chatroom_details_modal.html");
+/* harmony import */ var templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_12__);
+/* harmony import */ var templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! templates/chatroom_disconnect.html */ "./src/templates/chatroom_disconnect.html");
+/* harmony import */ var templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_13__);
+/* harmony import */ var templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! templates/chatroom_features.html */ "./src/templates/chatroom_features.html");
+/* harmony import */ var templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_14__);
+/* harmony import */ var templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! templates/chatroom_form.html */ "./src/templates/chatroom_form.html");
+/* harmony import */ var templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_15__);
+/* harmony import */ var templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! templates/chatroom_head.html */ "./src/templates/chatroom_head.html");
+/* harmony import */ var templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_16__);
+/* harmony import */ var templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! templates/chatroom_invite.html */ "./src/templates/chatroom_invite.html");
+/* harmony import */ var templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_17__);
+/* harmony import */ var templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! templates/chatroom_nickname_form.html */ "./src/templates/chatroom_nickname_form.html");
+/* harmony import */ var templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_18__);
+/* harmony import */ var templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! templates/chatroom_password_form.html */ "./src/templates/chatroom_password_form.html");
+/* harmony import */ var templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_19__);
+/* harmony import */ var templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! templates/chatroom_sidebar.html */ "./src/templates/chatroom_sidebar.html");
+/* harmony import */ var templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_20__);
+/* harmony import */ var templates_info_html__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! templates/info.html */ "./src/templates/info.html");
+/* harmony import */ var templates_info_html__WEBPACK_IMPORTED_MODULE_21___default = /*#__PURE__*/__webpack_require__.n(templates_info_html__WEBPACK_IMPORTED_MODULE_21__);
+/* harmony import */ var templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! templates/list_chatrooms_modal.html */ "./src/templates/list_chatrooms_modal.html");
+/* harmony import */ var templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_22__);
+/* harmony import */ var templates_occupant_html__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! templates/occupant.html */ "./src/templates/occupant.html");
+/* harmony import */ var templates_occupant_html__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(templates_occupant_html__WEBPACK_IMPORTED_MODULE_23__);
+/* harmony import */ var templates_room_description_html__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! templates/room_description.html */ "./src/templates/room_description.html");
+/* harmony import */ var templates_room_description_html__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(templates_room_description_html__WEBPACK_IMPORTED_MODULE_24__);
+/* harmony import */ var templates_room_item_html__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! templates/room_item.html */ "./src/templates/room_item.html");
+/* harmony import */ var templates_room_item_html__WEBPACK_IMPORTED_MODULE_25___default = /*#__PURE__*/__webpack_require__.n(templates_room_item_html__WEBPACK_IMPORTED_MODULE_25__);
+/* harmony import */ var templates_room_panel_html__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! templates/room_panel.html */ "./src/templates/room_panel.html");
+/* harmony import */ var templates_room_panel_html__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(templates_room_panel_html__WEBPACK_IMPORTED_MODULE_26__);
+/* harmony import */ var templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! templates/rooms_results.html */ "./src/templates/rooms_results.html");
+/* harmony import */ var templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_27__);
+/* harmony import */ var templates_spinner_html__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! templates/spinner.html */ "./src/templates/spinner.html");
+/* harmony import */ var templates_spinner_html__WEBPACK_IMPORTED_MODULE_28___default = /*#__PURE__*/__webpack_require__.n(templates_spinner_html__WEBPACK_IMPORTED_MODULE_28__);
+/* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! xss */ "./node_modules/xss/dist/xss.js");
+/* harmony import */ var xss__WEBPACK_IMPORTED_MODULE_29___default = /*#__PURE__*/__webpack_require__.n(xss__WEBPACK_IMPORTED_MODULE_29__);
 // Converse.js
 // Converse.js
 // https://conversejs.org
 // https://conversejs.org
 //
 //
@@ -53326,6 +53328,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
 
 
 
+
 
 
 
 
 const _converse$env = _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].env,
 const _converse$env = _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].env,
@@ -53510,7 +53513,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       // All MUC features found here: https://xmpp.org/registrar/disco-features.html
       // All MUC features found here: https://xmpp.org/registrar/disco-features.html
       el.querySelector('span.spinner').remove();
       el.querySelector('span.spinner').remove();
       el.querySelector('a.room-info').classList.add('selected');
       el.querySelector('a.room-info').classList.add('selected');
-      el.insertAdjacentHTML('beforeEnd', templates_room_description_html__WEBPACK_IMPORTED_MODULE_23___default()({
+      el.insertAdjacentHTML('beforeEnd', templates_room_description_html__WEBPACK_IMPORTED_MODULE_24___default()({
         'jid': stanza.getAttribute('from'),
         'jid': stanza.getAttribute('from'),
         'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
         'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
         'occ': _.get(_.head(sizzle('field[var="muc#roominfo_occupants"] value', stanza)), 'textContent'),
         'occ': _.get(_.head(sizzle('field[var="muc#roominfo_occupants"] value', stanza)), 'textContent'),
@@ -53552,7 +53555,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         u.slideIn(div_el).then(u.removeElement);
         u.slideIn(div_el).then(u.removeElement);
         parent_el.querySelector('a.room-info').classList.remove('selected');
         parent_el.querySelector('a.room-info').classList.remove('selected');
       } else {
       } else {
-        parent_el.insertAdjacentHTML('beforeend', templates_spinner_html__WEBPACK_IMPORTED_MODULE_27___default()());
+        parent_el.insertAdjacentHTML('beforeend', templates_spinner_html__WEBPACK_IMPORTED_MODULE_28___default()());
 
 
         _converse.api.disco.info(ev.target.getAttribute('data-room-jid'), null).then(stanza => insertRoomInfo(parent_el, stanza)).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
         _converse.api.disco.info(ev.target.getAttribute('data-room-jid'), null).then(stanza => insertRoomInfo(parent_el, stanza)).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
       }
       }
@@ -53580,7 +53583,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       toHTML() {
       toHTML() {
         const muc_domain = this.model.get('muc_domain') || _converse.muc_domain;
         const muc_domain = this.model.get('muc_domain') || _converse.muc_domain;
 
 
-        return templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_21___default()(_.extend(this.model.toJSON(), {
+        return templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_22___default()(_.extend(this.model.toJSON(), {
           'heading_list_chatrooms': __('Query for Groupchats'),
           'heading_list_chatrooms': __('Query for Groupchats'),
           'label_server_address': __('Server address'),
           'label_server_address': __('Server address'),
           'label_query': __('Show groupchats'),
           'label_query': __('Show groupchats'),
@@ -53622,7 +53625,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       roomStanzaItemToHTMLElement(groupchat) {
       roomStanzaItemToHTMLElement(groupchat) {
         const name = Strophe.unescapeNode(groupchat.getAttribute('name') || groupchat.getAttribute('jid'));
         const name = Strophe.unescapeNode(groupchat.getAttribute('name') || groupchat.getAttribute('jid'));
         const div = document.createElement('div');
         const div = document.createElement('div');
-        div.innerHTML = templates_room_item_html__WEBPACK_IMPORTED_MODULE_24___default()({
+        div.innerHTML = templates_room_item_html__WEBPACK_IMPORTED_MODULE_25___default()({
           'name': Strophe.xmlunescape(name),
           'name': Strophe.xmlunescape(name),
           'jid': groupchat.getAttribute('jid'),
           'jid': groupchat.getAttribute('jid'),
           'open_title': __('Click to open this groupchat'),
           'open_title': __('Click to open this groupchat'),
@@ -53637,7 +53640,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
       informNoRoomsFound() {
       informNoRoomsFound() {
         const chatrooms_el = this.el.querySelector('.available-chatrooms');
         const chatrooms_el = this.el.querySelector('.available-chatrooms');
-        chatrooms_el.innerHTML = templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_26___default()({
+        chatrooms_el.innerHTML = templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_27___default()({
           'feedback_text': __('No groupchats found')
           'feedback_text': __('No groupchats found')
         });
         });
         const input_el = this.el.querySelector('input[name="server"]');
         const input_el = this.el.querySelector('input[name="server"]');
@@ -53653,7 +53656,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         this.rooms = iq.querySelectorAll('query item');
         this.rooms = iq.querySelectorAll('query item');
 
 
         if (this.rooms.length) {
         if (this.rooms.length) {
-          available_chatrooms.innerHTML = templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_26___default()({
+          available_chatrooms.innerHTML = templates_rooms_results_html__WEBPACK_IMPORTED_MODULE_27___default()({
             'feedback_text': __('Groupchats found:')
             'feedback_text': __('Groupchats found:')
           });
           });
           const fragment = document.createDocumentFragment();
           const fragment = document.createDocumentFragment();
@@ -53795,13 +53798,13 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       },
       },
 
 
       toHTML() {
       toHTML() {
-        return templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_11___default()(_.extend(this.model.toJSON(), {
+        return templates_chatroom_details_modal_html__WEBPACK_IMPORTED_MODULE_12___default()(_.extend(this.model.toJSON(), {
           '_': _,
           '_': _,
           '__': __,
           '__': __,
           'display_name': __('Groupchat info for %1$s', this.model.getDisplayName()),
           'display_name': __('Groupchat info for %1$s', this.model.getDisplayName()),
           'features': this.model.features.toJSON(),
           'features': this.model.features.toJSON(),
           'num_occupants': this.model.occupants.length,
           'num_occupants': this.model.occupants.length,
-          'topic': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_28___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
+          'topic': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_29___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
             'whiteList': {}
             'whiteList': {}
           }))
           }))
         }));
         }));
@@ -53855,6 +53858,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         this.model.on('change:connection_status', this.afterConnected, this);
         this.model.on('change:connection_status', this.afterConnected, this);
         this.model.on('change:jid', this.renderHeading, this);
         this.model.on('change:jid', this.renderHeading, this);
         this.model.on('change:name', this.renderHeading, this);
         this.model.on('change:name', this.renderHeading, this);
+        this.model.on('change:role', this.renderBottomPanel, this);
         this.model.on('change:subject', this.renderHeading, this);
         this.model.on('change:subject', this.renderHeading, this);
         this.model.on('change:subject', this.setChatRoomSubject, this);
         this.model.on('change:subject', this.setChatRoomSubject, this);
         this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this);
         this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this);
@@ -53906,8 +53910,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         this.el.innerHTML = templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9___default()();
         this.el.innerHTML = templates_chatroom_html__WEBPACK_IMPORTED_MODULE_9___default()();
         this.renderHeading();
         this.renderHeading();
         this.renderChatArea();
         this.renderChatArea();
-        this.renderMessageForm();
-        this.initMentionAutoComplete();
+        this.renderBottomPanel();
 
 
         if (this.model.get('connection_status') !== _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].ROOMSTATUS.ENTERED) {
         if (this.model.get('connection_status') !== _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].ROOMSTATUS.ENTERED) {
           this.showSpinner();
           this.showSpinner();
@@ -53921,6 +53924,21 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
         this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
       },
       },
 
 
+      renderBottomPanel() {
+        const container = this.el.querySelector('.bottom-panel');
+
+        if (this.model.get('role') === 'visitor') {
+          container.innerHTML = templates_chatroom_bottom_panel_html__WEBPACK_IMPORTED_MODULE_10___default()({
+            '__': __
+          });
+        } else {
+          if (!container.firstElementChild || !container.querySelector('.sendXMPPMessage')) {
+            this.renderMessageForm();
+            this.initMentionAutoComplete();
+          }
+        }
+      },
+
       renderChatArea() {
       renderChatArea() {
         /* Render the UI container in which groupchat messages will appear.
         /* Render the UI container in which groupchat messages will appear.
          */
          */
@@ -54049,13 +54067,13 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       generateHeadingHTML() {
       generateHeadingHTML() {
         /* Returns the heading HTML to be rendered.
         /* Returns the heading HTML to be rendered.
          */
          */
-        return templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_15___default()(_.extend(this.model.toJSON(), {
+        return templates_chatroom_head_html__WEBPACK_IMPORTED_MODULE_16___default()(_.extend(this.model.toJSON(), {
           '_converse': _converse,
           '_converse': _converse,
           'Strophe': Strophe,
           'Strophe': Strophe,
           'info_close': __('Close and leave this groupchat'),
           'info_close': __('Close and leave this groupchat'),
           'info_configure': __('Configure this groupchat'),
           'info_configure': __('Configure this groupchat'),
           'info_details': __('Show more details about this groupchat'),
           'info_details': __('Show more details about this groupchat'),
-          'description': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_28___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
+          'description': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_29___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
             'whiteList': {}
             'whiteList': {}
           }))
           }))
         }));
         }));
@@ -54549,7 +54567,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
         _.each(container_el.children, u.hideElement);
         _.each(container_el.children, u.hideElement);
 
 
-        container_el.insertAdjacentHTML('beforeend', templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_14___default()());
+        container_el.insertAdjacentHTML('beforeend', templates_chatroom_form_html__WEBPACK_IMPORTED_MODULE_15___default()());
 
 
         const form_el = container_el.querySelector('form.chatroom-form'),
         const form_el = container_el.querySelector('form.chatroom-form'),
               fieldset_el = form_el.querySelector('fieldset'),
               fieldset_el = form_el.querySelector('fieldset'),
@@ -54628,7 +54646,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
           nick_el.classList.remove('error');
           nick_el.classList.remove('error');
         }
         }
 
 
-        this.el.querySelector('.chatroom-form-container').outerHTML = templates_spinner_html__WEBPACK_IMPORTED_MODULE_27___default()();
+        this.el.querySelector('.chatroom-form-container').outerHTML = templates_spinner_html__WEBPACK_IMPORTED_MODULE_28___default()();
         this.join(nick);
         this.join(nick);
       },
       },
 
 
@@ -54706,7 +54724,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         }
         }
 
 
         const container_el = this.el.querySelector('.chatroom-body');
         const container_el = this.el.querySelector('.chatroom-body');
-        container_el.insertAdjacentHTML('beforeend', templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_17___default()({
+        container_el.insertAdjacentHTML('beforeend', templates_chatroom_nickname_form_html__WEBPACK_IMPORTED_MODULE_18___default()({
           heading: __('Please choose your nickname'),
           heading: __('Please choose your nickname'),
           label_nickname: __('Nickname'),
           label_nickname: __('Nickname'),
           label_join: __('Enter groupchat'),
           label_join: __('Enter groupchat'),
@@ -54733,7 +54751,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
         _.each(this.el.querySelectorAll('.chatroom-form-container'), u.removeElement);
         _.each(this.el.querySelectorAll('.chatroom-form-container'), u.removeElement);
 
 
-        container_el.insertAdjacentHTML('beforeend', templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_18___default()({
+        container_el.insertAdjacentHTML('beforeend', templates_chatroom_password_form_html__WEBPACK_IMPORTED_MODULE_19___default()({
           'heading': __('This groupchat requires a password'),
           'heading': __('This groupchat requires a password'),
           'label_password': __('Password: '),
           'label_password': __('Password: '),
           'label_submit': __('Submit')
           'label_submit': __('Submit')
@@ -54754,7 +54772,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
         const reason = _.get(sizzle('text[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', error).pop(), 'textContent');
         const reason = _.get(sizzle('text[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', error).pop(), 'textContent');
 
 
-        container.innerHTML = templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_10___default()({
+        container.innerHTML = templates_chatroom_destroyed_html__WEBPACK_IMPORTED_MODULE_11___default()({
           '_': _,
           '_': _,
           '__': __,
           '__': __,
           'jid': moved_jid,
           'jid': moved_jid,
@@ -54786,7 +54804,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         _.each(this.el.querySelectorAll('.spinner'), u.removeElement);
         _.each(this.el.querySelectorAll('.spinner'), u.removeElement);
 
 
         const container = this.el.querySelector('.disconnect-container');
         const container = this.el.querySelector('.disconnect-container');
-        container.innerHTML = templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_12___default()({
+        container.innerHTML = templates_chatroom_disconnect_html__WEBPACK_IMPORTED_MODULE_13___default()({
           '_': _,
           '_': _,
           'disconnect_messages': msgs
           'disconnect_messages': msgs
         });
         });
@@ -54925,7 +54943,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         }
         }
 
 
         _.each(notification.messages, message => {
         _.each(notification.messages, message => {
-          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()({
+          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()({
             'isodate': moment().format(),
             'isodate': moment().format(),
             'extra_classes': 'chat-event',
             'extra_classes': 'chat-event',
             'message': message
             'message': message
@@ -55017,7 +55035,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
             'message': message
             'message': message
           };
           };
           this.content.removeChild(prev_info_el);
           this.content.removeChild(prev_info_el);
-          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
           const el = this.content.lastElementChild;
           const el = this.content.lastElementChild;
           setTimeout(() => u.addClass('fade-out', el), 5000);
           setTimeout(() => u.addClass('fade-out', el), 5000);
           setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5500);
           setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5500);
@@ -55040,9 +55058,9 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
           if (prev_info_el) {
           if (prev_info_el) {
             this.content.removeChild(prev_info_el);
             this.content.removeChild(prev_info_el);
-            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
           } else {
           } else {
-            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
             this.insertDayIndicator(this.content.lastElementChild);
             this.insertDayIndicator(this.content.lastElementChild);
           }
           }
         }
         }
@@ -55077,7 +55095,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
             'message': message
             'message': message
           };
           };
           this.content.removeChild(prev_info_el);
           this.content.removeChild(prev_info_el);
-          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
           const el = this.content.lastElementChild;
           const el = this.content.lastElementChild;
           setTimeout(() => u.addClass('fade-out', el), 5000);
           setTimeout(() => u.addClass('fade-out', el), 5000);
           setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5500);
           setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5500);
@@ -55100,9 +55118,9 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
           if (prev_info_el) {
           if (prev_info_el) {
             this.content.removeChild(prev_info_el);
             this.content.removeChild(prev_info_el);
-            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
           } else {
           } else {
-            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()(data));
+            this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()(data));
             this.insertDayIndicator(this.content.lastElementChild);
             this.insertDayIndicator(this.content.lastElementChild);
           }
           }
         }
         }
@@ -55191,7 +55209,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         u.removeElement(this.el.querySelector('.spinner'));
         u.removeElement(this.el.querySelector('.spinner'));
         const container_el = this.el.querySelector('.chatroom-body');
         const container_el = this.el.querySelector('.chatroom-body');
         const children = Array.prototype.slice.call(container_el.children, 0);
         const children = Array.prototype.slice.call(container_el.children, 0);
-        container_el.insertAdjacentHTML('afterbegin', templates_spinner_html__WEBPACK_IMPORTED_MODULE_27___default()());
+        container_el.insertAdjacentHTML('afterbegin', templates_spinner_html__WEBPACK_IMPORTED_MODULE_28___default()());
 
 
         _.each(children, u.hideElement);
         _.each(children, u.hideElement);
       },
       },
@@ -55218,17 +55236,17 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         const subject = this.model.get('subject'),
         const subject = this.model.get('subject'),
               message = subject.text ? __('Topic set by %1$s', subject.author) : __('Topic cleared by %1$s', subject.author),
               message = subject.text ? __('Topic set by %1$s', subject.author) : __('Topic cleared by %1$s', subject.author),
               date = moment().format();
               date = moment().format();
-        this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()({
+        this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()({
           'isodate': date,
           'isodate': date,
           'extra_classes': 'chat-event',
           'extra_classes': 'chat-event',
           'message': message
           'message': message
         }));
         }));
 
 
         if (subject.text) {
         if (subject.text) {
-          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_20___default()({
+          this.content.insertAdjacentHTML('beforeend', templates_info_html__WEBPACK_IMPORTED_MODULE_21___default()({
             'isodate': date,
             'isodate': date,
             'extra_classes': 'chat-topic',
             'extra_classes': 'chat-topic',
-            'message': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_28___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
+            'message': u.addHyperlinks(xss__WEBPACK_IMPORTED_MODULE_29___default.a.filterXSS(_.get(this.model.get('subject'), 'text'), {
               'whiteList': {}
               'whiteList': {}
             })),
             })),
             'render_message': true
             'render_message': true
@@ -55251,7 +55269,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       },
       },
 
 
       render() {
       render() {
-        this.el.innerHTML = templates_room_panel_html__WEBPACK_IMPORTED_MODULE_25___default()({
+        this.el.innerHTML = templates_room_panel_html__WEBPACK_IMPORTED_MODULE_26___default()({
           'heading_chatrooms': __('Groupchats'),
           'heading_chatrooms': __('Groupchats'),
           'title_new_room': __('Add a new groupchat'),
           'title_new_room': __('Add a new groupchat'),
           'title_list_rooms': __('Query for groupchats')
           'title_list_rooms': __('Query for groupchats')
@@ -55289,7 +55307,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
       toHTML() {
       toHTML() {
         const show = this.model.get('show');
         const show = this.model.get('show');
-        return templates_occupant_html__WEBPACK_IMPORTED_MODULE_22___default()(_.extend({
+        return templates_occupant_html__WEBPACK_IMPORTED_MODULE_23___default()(_.extend({
           '_': _,
           '_': _,
           'jid': '',
           'jid': '',
           'show': show,
           'show': show,
@@ -55334,7 +55352,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
       },
       },
 
 
       render() {
       render() {
-        this.el.innerHTML = templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_19___default()(_.extend(this.chatroomview.model.toJSON(), {
+        this.el.innerHTML = templates_chatroom_sidebar_html__WEBPACK_IMPORTED_MODULE_20___default()(_.extend(this.chatroomview.model.toJSON(), {
           'allow_muc_invitations': _converse.allow_muc_invitations,
           'allow_muc_invitations': _converse.allow_muc_invitations,
           'label_occupants': __('Participants')
           'label_occupants': __('Participants')
         }));
         }));
@@ -55352,7 +55370,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
         if (this.shouldInviteWidgetBeShown()) {
         if (this.shouldInviteWidgetBeShown()) {
           if (_.isNull(widget)) {
           if (_.isNull(widget)) {
             const heading = this.el.querySelector('.occupants-heading');
             const heading = this.el.querySelector('.occupants-heading');
-            heading.insertAdjacentHTML('afterend', templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_16___default()({
+            heading.insertAdjacentHTML('afterend', templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_17___default()({
               'error_message': null,
               'error_message': null,
               'label_invitation': __('Invite')
               'label_invitation': __('Invite')
             }));
             }));
@@ -55372,7 +55390,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
 
 
         if (_.reduce(_.values(picks), iteratee)) {
         if (_.reduce(_.values(picks), iteratee)) {
           const el = this.el.querySelector('.chatroom-features');
           const el = this.el.querySelector('.chatroom-features');
-          el.innerHTML = templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_13___default()(_.extend(features.toJSON(), {
+          el.innerHTML = templates_chatroom_features_html__WEBPACK_IMPORTED_MODULE_14___default()(_.extend(features.toJSON(), {
             __
             __
           }));
           }));
           this.setOccupantsHeight();
           this.setOccupantsHeight();
@@ -55414,7 +55432,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
               jid = el.value;
               jid = el.value;
 
 
         if (!jid || _.compact(jid.split('@')).length < 2) {
         if (!jid || _.compact(jid.split('@')).length < 2) {
-          evt.target.outerHTML = templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_16___default()({
+          evt.target.outerHTML = templates_chatroom_invite_html__WEBPACK_IMPORTED_MODULE_17___default()({
             'error_message': __('Please enter a valid XMPP address'),
             'error_message': __('Please enter a valid XMPP address'),
             'label_invitation': __('Invite')
             'label_invitation': __('Invite')
           });
           });
@@ -62528,6 +62546,11 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
         return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
       },
       },
 
 
+      getErrorMessage(stanza) {
+        const error = stanza.querySelector('error');
+        return _.propertyOf(error.querySelector('text'))('textContent') || __('Sorry, an error occurred:') + ' ' + error.innerHTML;
+      },
+
       getMessageBody(stanza) {
       getMessageBody(stanza) {
         /* Given a message stanza, return the text contained in its body.
         /* Given a message stanza, return the text contained in its body.
          */
          */
@@ -62748,11 +62771,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         chatbox.messages.create(attrs);
         chatbox.messages.create(attrs);
       },
       },
 
 
-      getErrorMessage(stanza) {
-        const error = stanza.querySelector('error');
-        return _.propertyOf(error.querySelector('text'))('textContent') || __('Sorry, an error occurred:') + ' ' + error.innerHTML;
-      },
-
       /**
       /**
        * Handler method for all incoming single-user chat "message" stanzas.
        * Handler method for all incoming single-user chat "message" stanzas.
        * @private
        * @private
@@ -67302,7 +67320,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
        */
        */
       saveAffiliationAndRole(pres) {
       saveAffiliationAndRole(pres) {
         const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
         const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
-        const is_self = pres.querySelector("status[code='110']");
+        const is_self = !_.isNull(pres.querySelector("status[code='110']"));
 
 
         if (is_self && !_.isNil(item)) {
         if (is_self && !_.isNil(item)) {
           const affiliation = item.getAttribute('affiliation');
           const affiliation = item.getAttribute('affiliation');
@@ -93027,7 +93045,7 @@ __p += '<!-- src/templates/chatarea.html -->\n<div class="chat-area col-md-9 col
  if (o.show_send_button) { ;
  if (o.show_send_button) { ;
 __p += 'chat-content-sendbutton';
 __p += 'chat-content-sendbutton';
  } ;
  } ;
-__p += '" aria-live="polite"></div>\n    <div class="message-form-container"/>\n</div>\n';
+__p += '" aria-live="polite"></div>\n    <div class="bottom-panel"/>\n</div>\n';
 return __p
 return __p
 };
 };
 
 
@@ -93048,7 +93066,7 @@ __p += '<!-- src/templates/chatbox.html -->\n<div class="flyout box-flyout">\n
  if (o.show_send_button) { ;
  if (o.show_send_button) { ;
 __p += 'chat-content-sendbutton';
 __p += 'chat-content-sendbutton';
  } ;
  } ;
-__p += '" aria-live="polite"></div>\n        <div class="message-form-container"></div>\n    </div>\n</div>\n';
+__p += '" aria-live="polite"></div>\n        <div class="bottom-panel"></div>\n    </div>\n</div>\n';
 return __p
 return __p
 };
 };
 
 
@@ -93245,6 +93263,24 @@ return __p
 
 
 /***/ }),
 /***/ }),
 
 
+/***/ "./src/templates/chatroom_bottom_panel.html":
+/*!**************************************************!*\
+  !*** ./src/templates/chatroom_bottom_panel.html ***!
+  \**************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+var _ = {escape:__webpack_require__(/*! ./node_modules/lodash/escape.js */ "./node_modules/lodash/escape.js")};
+module.exports = function(o) {
+var __t, __p = '', __e = _.escape;
+__p += '<!-- src/templates/chatroom_bottom_panel.html -->\n<div class="muc-bottom-panel">' +
+__e(o.__("You're not allowed to send messages in this room")) +
+'</div>\n';
+return __p
+};
+
+/***/ }),
+
 /***/ "./src/templates/chatroom_destroyed.html":
 /***/ "./src/templates/chatroom_destroyed.html":
 /*!***********************************************!*\
 /*!***********************************************!*\
   !*** ./src/templates/chatroom_destroyed.html ***!
   !*** ./src/templates/chatroom_destroyed.html ***!

+ 9 - 0
sass/_chatrooms.scss

@@ -306,6 +306,15 @@
             }
             }
         }
         }
 
 
+        .muc-bottom-panel {
+            border-top: var(--message-input-border-top);
+            height: 4em;
+            padding: 1em;
+            font-size: var(--font-size-small);
+            background-color: var(--chatroom-head-color);
+            color: white;
+        }
+
         .sendXMPPMessage {
         .sendXMPPMessage {
 
 
             .suggestion-box__results--above {
             .suggestion-box__results--above {

+ 4 - 4
spec/messages.js

@@ -1630,7 +1630,7 @@
                     let fullname = _converse.xmppstatus.get('fullname');
                     let fullname = _converse.xmppstatus.get('fullname');
                     fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname;
                     fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname;
                     await _converse.api.chats.open(sender_jid)
                     await _converse.api.chats.open(sender_jid)
-                    var msg_text = 'This message will not be sent, due to an error';
+                    let msg_text = 'This message will not be sent, due to an error';
                     const view = _converse.api.chatviews.get(sender_jid);
                     const view = _converse.api.chatviews.get(sender_jid);
                     let message = view.model.messages.create({
                     let message = view.model.messages.create({
                         'msgid': '82bc02ce-9651-4336-baf0-fa04762ed8d2',
                         'msgid': '82bc02ce-9651-4336-baf0-fa04762ed8d2',
@@ -1639,7 +1639,7 @@
                         'time': moment().format(),
                         'time': moment().format(),
                         'message': msg_text
                         'message': msg_text
                     });
                     });
-                    view.model.sendMessage(message);
+                    view.model.sendMessage(msg_text);
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     const chat_content = view.el.querySelector('.chat-content');
                     const chat_content = view.el.querySelector('.chat-content');
                     let msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
                     let msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
@@ -1656,7 +1656,7 @@
                         'time': moment().format(),
                         'time': moment().format(),
                         'message': msg_text
                         'message': msg_text
                     });
                     });
-                    view.model.sendMessage(message);
+                    view.model.sendMessage(msg_text);
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
                     msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
                     expect(msg_txt).toEqual(msg_text);
                     expect(msg_txt).toEqual(msg_text);
@@ -1724,7 +1724,7 @@
                         'time': moment().format(),
                         'time': moment().format(),
                         'message': msg_text
                         'message': msg_text
                     });
                     });
-                    view.model.sendMessage(message);
+                    view.model.sendMessage(msg_text);
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     await new Promise((resolve, reject) => view.once('messageInserted', resolve));
                     msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
                     msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
                     expect(msg_txt).toEqual(msg_text);
                     expect(msg_txt).toEqual(msg_text);

+ 0 - 6
spec/muc.js

@@ -4645,12 +4645,6 @@
                     async function (done, _converse) {
                     async function (done, _converse) {
 
 
                 await test_utils.openAndEnterChatRoom(_converse, 'trollbox', 'localhost', 'troll');
                 await test_utils.openAndEnterChatRoom(_converse, 'trollbox', 'localhost', 'troll');
-                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);
-                });
                 const view = _converse.chatboxviews.get('trollbox@localhost');
                 const view = _converse.chatboxviews.get('trollbox@localhost');
                 const textarea = view.el.querySelector('.chat-textarea');
                 const textarea = view.el.querySelector('.chat-textarea');
                 textarea.value = 'Hello world';
                 textarea.value = 'Hello world';

+ 1 - 1
src/converse-chatview.js

@@ -402,7 +402,7 @@ converse.plugins.add('converse-chatview', {
                 } else {
                 } else {
                     placeholder = __('Message');
                     placeholder = __('Message');
                 }
                 }
-                const form_container = this.el.querySelector('.message-form-container');
+                const form_container = this.el.querySelector('.bottom-panel');
                 form_container.innerHTML = tpl_chatbox_message_form(
                 form_container.innerHTML = tpl_chatbox_message_form(
                     _.extend(this.model.toJSON(), {
                     _.extend(this.model.toJSON(), {
                         'hint_value': _.get(this.el.querySelector('.spoiler-hint'), 'value'),
                         'hint_value': _.get(this.el.querySelector('.spoiler-hint'), 'value'),

+ 15 - 2
src/converse-muc-views.js

@@ -16,6 +16,7 @@ import muc_utils from "@converse/headless/utils/muc";
 import tpl_add_chatroom_modal from "templates/add_chatroom_modal.html";
 import tpl_add_chatroom_modal from "templates/add_chatroom_modal.html";
 import tpl_chatarea from "templates/chatarea.html";
 import tpl_chatarea from "templates/chatarea.html";
 import tpl_chatroom from "templates/chatroom.html";
 import tpl_chatroom from "templates/chatroom.html";
+import tpl_chatroom_bottom_panel from "templates/chatroom_bottom_panel.html";
 import tpl_chatroom_destroyed from "templates/chatroom_destroyed.html";
 import tpl_chatroom_destroyed from "templates/chatroom_destroyed.html";
 import tpl_chatroom_details_modal from "templates/chatroom_details_modal.html";
 import tpl_chatroom_details_modal from "templates/chatroom_details_modal.html";
 import tpl_chatroom_disconnect from "templates/chatroom_disconnect.html";
 import tpl_chatroom_disconnect from "templates/chatroom_disconnect.html";
@@ -539,6 +540,7 @@ converse.plugins.add('converse-muc-views', {
                 this.model.on('change:connection_status', this.afterConnected, this);
                 this.model.on('change:connection_status', this.afterConnected, this);
                 this.model.on('change:jid', this.renderHeading, this);
                 this.model.on('change:jid', this.renderHeading, this);
                 this.model.on('change:name', this.renderHeading, this);
                 this.model.on('change:name', this.renderHeading, this);
+                this.model.on('change:role', this.renderBottomPanel, this);
                 this.model.on('change:subject', this.renderHeading, this);
                 this.model.on('change:subject', this.renderHeading, this);
                 this.model.on('change:subject', this.setChatRoomSubject, this);
                 this.model.on('change:subject', this.setChatRoomSubject, this);
                 this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this);
                 this.model.on('configurationNeeded', this.getAndRenderConfigurationForm, this);
@@ -585,8 +587,7 @@ converse.plugins.add('converse-muc-views', {
                 this.el.innerHTML = tpl_chatroom();
                 this.el.innerHTML = tpl_chatroom();
                 this.renderHeading();
                 this.renderHeading();
                 this.renderChatArea();
                 this.renderChatArea();
-                this.renderMessageForm();
-                this.initMentionAutoComplete();
+                this.renderBottomPanel();
                 if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
                 if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
                     this.showSpinner();
                     this.showSpinner();
                 }
                 }
@@ -598,6 +599,18 @@ converse.plugins.add('converse-muc-views', {
                 this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
                 this.el.querySelector('.chat-head-chatroom').innerHTML = this.generateHeadingHTML();
             },
             },
 
 
+            renderBottomPanel () {
+                const container = this.el.querySelector('.bottom-panel');
+                if (this.model.get('role') === 'visitor') {
+                    container.innerHTML = tpl_chatroom_bottom_panel({'__': __});
+                } else {
+                    if (!container.firstElementChild || !container.querySelector('.sendXMPPMessage')) {
+                        this.renderMessageForm();
+                        this.initMentionAutoComplete();
+                    }
+                }
+            },
+
             renderChatArea () {
             renderChatArea () {
                 /* Render the UI container in which groupchat messages will appear.
                 /* Render the UI container in which groupchat messages will appear.
                  */
                  */

+ 6 - 6
src/headless/converse-chatboxes.js

@@ -696,6 +696,12 @@ converse.plugins.add('converse-chatboxes', {
                 return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
                 return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
             },
             },
 
 
+            getErrorMessage (stanza) {
+                const error = stanza.querySelector('error');
+                return _.propertyOf(error.querySelector('text'))('textContent') ||
+                    __('Sorry, an error occurred:') + ' ' + error.innerHTML;
+            },
+
             getMessageBody (stanza) {
             getMessageBody (stanza) {
                 /* Given a message stanza, return the text contained in its body.
                 /* Given a message stanza, return the text contained in its body.
                  */
                  */
@@ -899,12 +905,6 @@ converse.plugins.add('converse-chatboxes', {
                 chatbox.messages.create(attrs);
                 chatbox.messages.create(attrs);
             },
             },
 
 
-            getErrorMessage (stanza) {
-                const error = stanza.querySelector('error');
-                return _.propertyOf(error.querySelector('text'))('textContent') ||
-                    __('Sorry, an error occurred:') + ' ' + error.innerHTML;
-            },
-
             /**
             /**
              * Handler method for all incoming single-user chat "message" stanzas.
              * Handler method for all incoming single-user chat "message" stanzas.
              * @private
              * @private

+ 1 - 1
src/headless/converse-muc.js

@@ -718,7 +718,7 @@ converse.plugins.add('converse-muc', {
              */
              */
             saveAffiliationAndRole (pres) {
             saveAffiliationAndRole (pres) {
                 const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
                 const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
-                const is_self = pres.querySelector("status[code='110']");
+                const is_self = !_.isNull(pres.querySelector("status[code='110']"));
                 if (is_self && !_.isNil(item)) {
                 if (is_self && !_.isNil(item)) {
                     const affiliation = item.getAttribute('affiliation');
                     const affiliation = item.getAttribute('affiliation');
                     const role = item.getAttribute('role');
                     const role = item.getAttribute('role');

+ 6 - 6
src/headless/dist/converse-headless.js

@@ -41045,6 +41045,11 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
         return !_.isNil(sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop());
       },
       },
 
 
+      getErrorMessage(stanza) {
+        const error = stanza.querySelector('error');
+        return _.propertyOf(error.querySelector('text'))('textContent') || __('Sorry, an error occurred:') + ' ' + error.innerHTML;
+      },
+
       getMessageBody(stanza) {
       getMessageBody(stanza) {
         /* Given a message stanza, return the text contained in its body.
         /* Given a message stanza, return the text contained in its body.
          */
          */
@@ -41265,11 +41270,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
         chatbox.messages.create(attrs);
         chatbox.messages.create(attrs);
       },
       },
 
 
-      getErrorMessage(stanza) {
-        const error = stanza.querySelector('error');
-        return _.propertyOf(error.querySelector('text'))('textContent') || __('Sorry, an error occurred:') + ' ' + error.innerHTML;
-      },
-
       /**
       /**
        * Handler method for all incoming single-user chat "message" stanzas.
        * Handler method for all incoming single-user chat "message" stanzas.
        * @private
        * @private
@@ -45819,7 +45819,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins.add('converse-muc
        */
        */
       saveAffiliationAndRole(pres) {
       saveAffiliationAndRole(pres) {
         const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
         const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, pres).pop();
-        const is_self = pres.querySelector("status[code='110']");
+        const is_self = !_.isNull(pres.querySelector("status[code='110']"));
 
 
         if (is_self && !_.isNil(item)) {
         if (is_self && !_.isNil(item)) {
           const affiliation = item.getAttribute('affiliation');
           const affiliation = item.getAttribute('affiliation');

+ 1 - 1
src/templates/chatarea.html

@@ -1,4 +1,4 @@
 <div class="chat-area col-md-9 col-8">
 <div class="chat-area col-md-9 col-8">
     <div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite"></div>
     <div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite"></div>
-    <div class="message-form-container"/>
+    <div class="bottom-panel"/>
 </div>
 </div>

+ 1 - 1
src/templates/chatbox.html

@@ -1,6 +1,6 @@
 <div class="flyout box-flyout">
 <div class="flyout box-flyout">
     <div class="chat-body">
     <div class="chat-body">
         <div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite"></div>
         <div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite"></div>
-        <div class="message-form-container"></div>
+        <div class="bottom-panel"></div>
     </div>
     </div>
 </div>
 </div>

+ 1 - 0
src/templates/chatroom_bottom_panel.html

@@ -0,0 +1 @@
+<div class="muc-bottom-panel">{{{o.__("You're not allowed to send messages in this room")}}}</div>