Browse Source

Fixes #2745. Wraps MUC details in `converse-rich-text`

Also fixed an issue where the `config` model on the MUC wasn't being
properly persisted and fetched.
JC Brand 3 years ago
parent
commit
85d75a5494

+ 5 - 4
src/headless/plugins/muc/muc.js

@@ -137,7 +137,8 @@ const ChatRoomMixin = {
     async restoreFromCache () {
         if (this.isEntered() && (await this.isJoined())) {
             // We've restored the room from cache and we're still joined.
-            await new Promise(resolve => this.features.fetch({ 'success': resolve, 'error': resolve }));
+            await new Promise(r => this.features.fetch({ 'success': r, 'error': r }));
+            await new Promise(r => this.config.fetch({ 'success': r, 'error': r }));
             await this.fetchOccupants().catch(e => log.error(e));
             await this.fetchMessages().catch(e => log.error(e));
             return true;
@@ -387,8 +388,8 @@ const ChatRoomMixin = {
         this.features.browserStorage = _converse.createStore(id, 'session');
         this.features.listenTo(_converse, 'beforeLogout', () => this.features.browserStorage.flush());
 
-        id = `converse.muc-config-{_converse.bare_jid}-${this.get('jid')}`;
-        this.config = new Model();
+        id = `converse.muc-config-${_converse.bare_jid}-${this.get('jid')}`;
+        this.config = new Model({ id });
         this.config.browserStorage = _converse.createStore(id, 'session');
         this.config.listenTo(_converse, 'beforeLogout', () => this.config.browserStorage.flush());
     },
@@ -1139,7 +1140,7 @@ const ChatRoomMixin = {
         const fields = await api.disco.getFields(this.get('jid'));
         const config = fields.reduce((config, f) => {
             const name = f.get('var');
-            if (name && name.startsWith('muc#roominfo_')) {
+            if (name?.startsWith('muc#roominfo_')) {
                 config[name.replace('muc#roominfo_', '')] = f.get('value');
             }
             return config;

+ 2 - 0
src/plugins/muc-views/modals/muc-details.js

@@ -1,6 +1,8 @@
 import BaseModal from "plugins/modal/base.js";
 import tpl_muc_details from "./templates/muc-details.js";
 
+import '../styles/muc-details.scss';
+
 
 export default BaseModal.extend({
     id: "muc-details-modal",

+ 4 - 4
src/plugins/muc-views/modals/templates/muc-details.js

@@ -7,7 +7,7 @@ const subject = (o) => {
     const i18n_topic = __('Topic');
     const i18n_topic_author = __('Topic author');
     return html`
-        <p class="room-info"><strong>${i18n_topic}</strong>: ${o.subject.text}</p>
+        <p class="room-info"><strong>${i18n_topic}</strong>: <converse-rich-text text=${o.subject.text} render_styling></converse-rich-text></p>
         <p class="room-info"><strong>${i18n_topic_author}</strong>: ${o.subject && o.subject.author}</p>
     `;
 }
@@ -20,7 +20,7 @@ export default (model) => {
     const features = model.features.toJSON();
     const num_occupants = model.occupants.filter(o => o.get('show') !== 'offline').length;
 
-    const i18n_address =  __('Groupchat XMPP address');
+    const i18n_address =  __('XMPP address');
     const i18n_archiving = __('Message archiving');
     const i18n_archiving_help = __('Messages are archived on the server');
     const i18n_desc = __('Description');
@@ -61,8 +61,8 @@ export default (model) => {
                     <span class="modal-alert"></span>
                     <div class="room-info">
                         <p class="room-info"><strong>${i18n_name}</strong>: ${o.name}</p>
-                        <p class="room-info"><strong>${i18n_address}</strong>: ${o.jid}</p>
-                        <p class="room-info"><strong>${i18n_desc}</strong>: ${config.description}</p>
+                        <p class="room-info"><strong>${i18n_address}</strong>: <converse-rich-text text="xmpp:${o.jid}?join"></converse-rich-text></p>
+                        <p class="room-info"><strong>${i18n_desc}</strong>: <converse-rich-text text="${config.description}" render_styling></converse-rich-text></p>
                         ${ (o.subject) ? subject(o) : '' }
                         <p class="room-info"><strong>${i18n_online_users}</strong>: ${num_occupants}</p>
                         <p class="room-info"><strong>${i18n_features}</strong>:

+ 8 - 0
src/plugins/muc-views/styles/muc-details.scss

@@ -0,0 +1,8 @@
+#muc-details-modal {
+    .room-info {
+        strong {
+            color: var(--muc-color);
+        }
+    }
+}
+

+ 14 - 5
src/plugins/muc-views/tests/muclist.js

@@ -259,8 +259,12 @@ describe("A groupchat shown in the groupchats list", function () {
         await u.waitUntil(() => u.isVisible(modal.el), 1000);
         let els = modal.el.querySelectorAll('p.room-info');
         expect(els[0].textContent).toBe("Name: A Dark Cave")
-        expect(els[1].textContent).toBe("Groupchat XMPP address: coven@chat.shakespeare.lit")
-        expect(els[2].textContent).toBe("Description: This is the description")
+
+        expect(els[1].querySelector('strong').textContent).toBe("XMPP address");
+        expect(els[1].querySelector('converse-rich-text').textContent.trim()).toBe("xmpp:coven@chat.shakespeare.lit?join");
+        expect(els[2].querySelector('strong').textContent).toBe("Description");
+        expect(els[2].querySelector('converse-rich-text').textContent).toBe("This is the description");
+
         expect(els[3].textContent).toBe("Online users: 1")
         const features_list = modal.el.querySelector('.features-list');
         expect(features_list.textContent.replace(/(\n|\s{2,})/g, '')).toBe(
@@ -289,9 +293,14 @@ describe("A groupchat shown in the groupchats list", function () {
         view.model.set({'subject': {'author': 'someone', 'text': 'Hatching dark plots'}});
         els = modal.el.querySelectorAll('p.room-info');
         expect(els[0].textContent).toBe("Name: A Dark Cave")
-        expect(els[1].textContent).toBe("Groupchat XMPP address: coven@chat.shakespeare.lit")
-        expect(els[2].textContent).toBe("Description: This is the description")
-        expect(els[3].textContent).toBe("Topic: Hatching dark plots")
+
+        expect(els[1].querySelector('strong').textContent).toBe("XMPP address");
+        expect(els[1].querySelector('converse-rich-text').textContent.trim()).toBe("xmpp:coven@chat.shakespeare.lit?join");
+        expect(els[2].querySelector('strong').textContent).toBe("Description");
+        expect(els[2].querySelector('converse-rich-text').textContent).toBe("This is the description");
+        expect(els[3].querySelector('strong').textContent).toBe("Topic");
+        await u.waitUntil(() => els[3].querySelector('converse-rich-text').textContent === "Hatching dark plots");
+
         expect(els[4].textContent).toBe("Topic author: someone")
         expect(els[5].textContent).toBe("Online users: 2")
     }));

+ 1 - 1
src/shared/rich-text.js

@@ -123,7 +123,7 @@ export class RichText extends String {
      */
     addHyperlinks (text, local_offset) {
         const full_offset = local_offset + this.offset;
-        const urls_meta = this.media_urls || getMediaURLsMetadata(text).media_urls || [];
+        const urls_meta = this.media_urls || getMediaURLsMetadata(text, local_offset).media_urls || [];
         const media_urls = getMediaURLs(urls_meta, text, full_offset);
 
         media_urls.filter(o => !o.is_encrypted).forEach(url_obj => {