Browse Source

Combine RoomsPanel with RoomsList element

JC Brand 4 years ago
parent
commit
bb317d1abb

+ 30 - 28
spec/bookmarks.js

@@ -410,7 +410,7 @@ describe("Bookmarks", function () {
 
 
     it("can be retrieved from the XMPP server", mock.initConverse(
-            ['chatBoxesFetched', 'roomsPanelRendered', 'rosterGroupsFetched'], {},
+            ['chatBoxesFetched', 'rosterGroupsFetched'], {},
             async function (done, _converse) {
 
         const { Strophe, sizzle, u, $iq } = converse.env;
@@ -420,14 +420,14 @@ describe("Bookmarks", function () {
             ['http://jabber.org/protocol/pubsub#publish-options']
         );
         /* Client requests all items
-            * -------------------------
-            *
-            *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
-            *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-            *      <items node='storage:bookmarks'/>
-            *  </pubsub>
-            *  </iq>
-            */
+         * -------------------------
+         *
+         *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
+         *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+         *      <items node='storage:bookmarks'/>
+         *  </pubsub>
+         *  </iq>
+         */
         const IQ_stanzas = _converse.connection.IQ_stanzas;
         const sent_stanza = await u.waitUntil(
             () => IQ_stanzas.filter(s => sizzle('items[node="storage:bookmarks"]', s).length).pop());
@@ -487,7 +487,7 @@ describe("Bookmarks", function () {
         done();
     }));
 
-    describe("The rooms panel", function () {
+    describe("The bookmarks list", function () {
 
         it("shows a list of bookmarks", mock.initConverse(
             ['rosterGroupsFetched'], {},
@@ -649,19 +649,21 @@ describe("Bookmarks", function () {
                 'name':  'The Play',
                 'nick': ''
             });
-            const el = _converse.chatboxviews.el
+            const chats_el = document.querySelector('converse-chats');
             const selector = '#chatrooms .bookmarks.rooms-list .room-item';
-            await u.waitUntil(() => sizzle(selector, el).filter(u.isVisible).length);
-            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', el).pop())).toBeFalsy();
-            expect(sizzle(selector, el).filter(u.isVisible).length).toBe(1);
-            expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
-            sizzle('#chatrooms .bookmarks-toggle', el).pop().click();
-            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', el).pop())).toBeTruthy();
-            expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.CLOSED);
-            sizzle('#chatrooms .bookmarks-toggle', el).pop().click();
-            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', el).pop())).toBeFalsy();
-            expect(sizzle(selector, el).filter(u.isVisible).length).toBe(1);
-            expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
+            await u.waitUntil(() => sizzle(selector, chats_el).filter(u.isVisible).length);
+            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', chats_el).pop())).toBeFalsy();
+            expect(sizzle(selector, chats_el).filter(u.isVisible).length).toBe(1);
+
+            const bookmarks_el = chats_el.querySelector('converse-bookmarks');
+            expect(bookmarks_el.model.get('toggle-state')).toBe(_converse.OPENED);
+            sizzle('#chatrooms .bookmarks-toggle', chats_el).pop().click();
+            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', chats_el).pop())).toBeTruthy();
+            expect(bookmarks_el.model.get('toggle-state')).toBe(_converse.CLOSED);
+            sizzle('#chatrooms .bookmarks-toggle', chats_el).pop().click();
+            expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', chats_el).pop())).toBeFalsy();
+            expect(sizzle(selector, chats_el).filter(u.isVisible).length).toBe(1);
+            expect(bookmarks_el.model.get('toggle-state')).toBe(_converse.OPENED);
             done();
         }));
     });
@@ -688,20 +690,20 @@ describe("When hide_open_bookmarks is true and a bookmarked room is opened", fun
         expect(_converse.bookmarks.length).toBe(1);
 
         const u = converse.env.utils;
-        const bmarks_view = _converse.bookmarksview;
-        await u.waitUntil(() => bmarks_view.querySelectorAll(".open-room").length, 500);
-        const room_els = bmarks_view.querySelectorAll(".open-room");
+        const bookmarks_el = document.querySelector('converse-bookmarks');
+        await u.waitUntil(() => bookmarks_el.querySelectorAll(".open-room").length, 500);
+        const room_els = bookmarks_el.querySelectorAll(".open-room");
         expect(room_els.length).toBe(1);
 
-        const bookmark = _converse.bookmarksview.querySelector(".open-room");
+        const bookmark = bookmarks_el.querySelector(".open-room");
         bookmark.click();
         await u.waitUntil(() => _converse.chatboxviews.get(jid));
 
-        expect(u.hasClass('hidden', _converse.bookmarksview.querySelector(".available-chatroom"))).toBeTruthy();
+        expect(u.hasClass('hidden', bookmarks_el.querySelector(".available-chatroom"))).toBeTruthy();
         // Check that it reappears once the room is closed
         const view = _converse.chatboxviews.get(jid);
         view.close();
-        await u.waitUntil(() => !u.hasClass('hidden', _converse.bookmarksview.querySelector(".available-chatroom")));
+        await u.waitUntil(() => !u.hasClass('hidden', bookmarks_el.querySelector(".available-chatroom")));
         done();
     }));
 });

+ 1 - 1
spec/muclist.js

@@ -126,7 +126,7 @@ describe("A groupchat shown in the groupchats list", function () {
         expect(room_els.length).toBe(1);
 
         let item = room_els[0];
-        await u.waitUntil(() => lview.model.get(muc_jid).get('hidden') === false);
+        await u.waitUntil(() => _converse.chatboxes.get(muc_jid).get('hidden') === false);
         await u.waitUntil(() => u.hasClass('open', item), 1000);
         expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
         await _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'}, true);

+ 0 - 1
src/headless/core.js

@@ -742,7 +742,6 @@ export const api = _converse.api = {
      * * [rosterContactsFetched](/docs/html/events.html#rosterContactsFetched)
      * * [rosterGroupsFetched](/docs/html/events.html#rosterGroupsFetched)
      * * [rosterInitialized](/docs/html/events.html#rosterInitialized)
-     * * [roomsPanelRendered](/docs/html/events.html#roomsPanelRendered)
      *
      * The various plugins might also provide promises, and they do this by using the
      * `promises.add` api method.

+ 0 - 16
src/headless/plugins/muc/index.js

@@ -16,7 +16,6 @@ import muc_api from './api.js';
 import muc_utils from './utils.js';
 import u from '../../utils/form';
 import { Collection } from '@converse/skeletor/src/collection';
-import { Model } from '@converse/skeletor/src/model.js';
 import { _converse, api, converse } from '../../core.js';
 import { isObject } from 'lodash-es';
 
@@ -369,21 +368,6 @@ converse.plugins.add('converse-muc', {
         });
 
 
-        _converse.RoomsPanelModel = Model.extend({
-            defaults: function () {
-                return {
-                    'muc_domain': api.settings.get('muc_domain'),
-                    'nick': _converse.getDefaultMUCNickname()
-                };
-            },
-
-            setDomain (jid) {
-                if (!api.settings.get('locked_muc_domain')) {
-                    this.save('muc_domain', Strophe.getDomainFromJid(jid));
-                }
-            }
-        });
-
         /**
          * A direct MUC invitation to join a groupchat has been received
          * See XEP-0249: Direct MUC invitations.

+ 12 - 13
src/plugins/bookmark-views/bookmarks-list.js

@@ -10,31 +10,30 @@ export default class BookmarksView extends ElementView {
 
     async initialize () {
         await api.waitUntil('bookmarksInitialized');
-        this.model = _converse.bookmarks;
 
-        this.listenTo(this.model, 'add', this.render);
-        this.listenTo(this.model, 'remove', this.render);
+        this.listenTo(_converse.bookmarks, 'add', this.render);
+        this.listenTo(_converse.bookmarks, 'remove', this.render);
 
         this.listenTo(_converse.chatboxes, 'add', this.render);
         this.listenTo(_converse.chatboxes, 'remove', this.render);
 
         const id = `converse.room-bookmarks${_converse.bare_jid}-list-model`;
-        this.list_model = new _converse.BookmarksList({ id });
-        this.list_model.browserStorage = _converse.createStore(id);
-        this.list_model.fetch({ 'success': () => this.render(), 'error': () => this.render() });
+        this.model = new _converse.BookmarksList({ id });
+        this.model.browserStorage = _converse.createStore(id);
+        this.model.fetch({ 'success': () => this.render(), 'error': () => this.render() });
     }
 
     render () {
         const is_hidden = b => !!(api.settings.get('hide_open_bookmarks') && _converse.chatboxes.get(b.get('jid')));
         render(tpl_bookmarks_list({
             '_converse': _converse,
-            'bookmarks': this.model,
-            'hidden': this.model.getUnopenedBookmarks().length && true,
+            'bookmarks': _converse.bookmarks,
+            'hidden': _converse.bookmarks.getUnopenedBookmarks().length && true,
             'is_hidden': is_hidden,
             'openRoom': ev => this.openRoom(ev),
             'removeBookmark': ev => this.removeBookmark(ev),
             'toggleBookmarksList': ev => this.toggleBookmarksList(ev),
-            'toggle_state': this.list_model.get('toggle-state')
+            'toggle_state': this.model.get('toggle-state')
         }), this);
     }
 
@@ -58,15 +57,15 @@ export default class BookmarksView extends ElementView {
         }
         const icon_el = ev.target.matches('.fa') ? ev.target : ev.target.querySelector('.fa');
         if (u.hasClass('fa-caret-down', icon_el)) {
-            u.slideIn(this.el.querySelector('.bookmarks'));
-            this.list_model.save({ 'toggle-state': _converse.CLOSED });
+            u.slideIn(this.querySelector('.bookmarks'));
+            this.model.save({ 'toggle-state': _converse.CLOSED });
             icon_el.classList.remove('fa-caret-down');
             icon_el.classList.add('fa-caret-right');
         } else {
             icon_el.classList.remove('fa-caret-right');
             icon_el.classList.add('fa-caret-down');
-            u.slideOut(this.el.querySelector('.bookmarks'));
-            this.list_model.save({ 'toggle-state': _converse.OPENED });
+            u.slideOut(this.querySelector('.bookmarks'));
+            this.model.save({ 'toggle-state': _converse.OPENED });
         }
     }
 }

+ 5 - 3
src/plugins/controlbox/templates/controlbox.js

@@ -15,9 +15,11 @@ export default o => html`
                 ${o.connected
                     ? html`
                           <converse-user-profile></converse-user-profile>
-                          <converse-headlines-panel></converse-headlines-panel>
-                          <converse-rooms-list></converse-rooms-list>
-                          <converse-bookmarks></converse-bookmarks>`
+                          <converse-headlines-panel class="controlbox-section"></converse-headlines-panel>
+                          <div id="chatrooms" class="controlbox-section">
+                              <converse-rooms-list></converse-rooms-list>
+                              <converse-bookmarks></converse-bookmarks>
+                          </div>`
                     : o['active-form'] === 'register'
                         ? html`<converse-register-panel></converse-register-panel>`
                         : html`<converse-login-panel></converse-login-panel>`

+ 0 - 2
src/plugins/muc-views/index.js

@@ -94,8 +94,6 @@ converse.plugins.add('converse-muc-views', {
     initialize () {
         const { _converse } = this;
 
-        api.promises.add(['roomsPanelRendered']);
-
         // Configuration values for this plugin
         // ====================================
         // Refer to docs/source/configuration.rst for explanations of these

+ 1 - 63
src/plugins/muc-views/rooms-panel.js

@@ -1,74 +1,12 @@
-import AddMUCModal from 'modals/add-muc.js';
-import tpl_room_panel from 'templates/room_panel.js';
-import { View } from '@converse/skeletor/src/view.js';
-import MUCListModal from 'modals/muc-list.js';
-import { _converse, api, converse } from '@converse/headless/core';
-import { __ } from 'i18n';
+import { converse } from '@converse/headless/core';
 
 const u = converse.env.utils;
 
-/**
- * View which renders MUC section of the control box.
- * @class
- * @namespace _converse.RoomsPanel
- * @memberOf _converse
- */
-export const RoomsPanel = View.extend({
-    tagName: 'div',
-    className: 'controlbox-section',
-    id: 'chatrooms',
-    events: {
-        'click a.controlbox-heading__btn.show-add-muc-modal': 'showAddRoomModal',
-        'click a.controlbox-heading__btn.show-list-muc-modal': 'showMUCListModal'
-    },
-
-    toHTML () {
-        return tpl_room_panel({
-            'heading_chatrooms': __('Groupchats'),
-            'title_new_room': __('Add a new groupchat'),
-            'title_list_rooms': __('Query for groupchats')
-        });
-    },
-
-    showAddRoomModal (ev) {
-        api.modal.show(AddMUCModal, { 'model': this.model }, ev);
-    },
-
-    showMUCListModal (ev) {
-        api.modal.show(MUCListModal, { 'model': this.model }, ev);
-    }
-});
-
 /**
  * Mixin which adds the ability to a ControlBox to render a list of open groupchats
  * @mixin
  */
 export const RoomsPanelViewMixin = {
-    renderRoomsPanel () {
-        if (this.roomspanel && u.isInDOM(this.roomspanel.el)) {
-            return this.roomspanel;
-        }
-        const id = `converse.roomspanel${_converse.bare_jid}`;
-
-        this.roomspanel = new _converse.RoomsPanel({
-            'model': new (_converse.RoomsPanelModel.extend({
-                id,
-                'browserStorage': _converse.createStore(id)
-            }))()
-        });
-        this.roomspanel.model.fetch();
-        this.querySelector('.controlbox-pane').insertAdjacentElement('beforeEnd', this.roomspanel.render().el);
-
-        /**
-         * Triggered once the section of the { @link _converse.ControlBoxView }
-         * which shows gropuchats has been rendered.
-         * @event _converse#roomsPanelRendered
-         * @example _converse.api.listen.on('roomsPanelRendered', () => { ... });
-         */
-        api.trigger('roomsPanelRendered');
-        return this.roomspanel;
-    },
-
     getRoomsPanel () {
         if (this.roomspanel && u.isInDOM(this.roomspanel.el)) {
             return this.roomspanel;

+ 1 - 16
src/plugins/roomslist/index.js

@@ -7,28 +7,14 @@
  */
 import "@converse/headless/plugins/muc/index.js";
 import './view.js';
-import RoomsList from './model.js';
 import { _converse, api, converse } from "@converse/headless/core";
 
 
 converse.plugins.add('converse-roomslist', {
-    /* Dependencies are other plugins which might be
-     * overridden or relied upon, and therefore need to be loaded before
-     * this plugin. They are called "optional" because they might not be
-     * available, in which case any overrides applicable to them will be
-     * ignored.
-     *
-     * It's possible however to make optional dependencies non-optional.
-     * If the setting "strict_plugin_dependencies" is set to true,
-     * an error will be raised if the plugin is not found.
-     *
-     * NB: These plugins need to have already been loaded via require.js.
-     */
+
     dependencies: ["converse-singleton", "converse-controlbox", "converse-muc", "converse-bookmarks"],
 
     initialize () {
-        _converse.RoomsList= RoomsList;
-
         // Event handlers
         api.listen.on('connected', async () =>  {
             if (_converse.allow_bookmarks) {
@@ -36,7 +22,6 @@ converse.plugins.add('converse-roomslist', {
             } else {
                 await Promise.all([
                     api.waitUntil('chatBoxesFetched'),
-                    api.waitUntil('roomsPanelRendered')
                 ]);
             }
         });

+ 0 - 9
src/plugins/roomslist/model.js

@@ -1,9 +0,0 @@
-import { _converse } from "@converse/headless/core";
-import { Model } from '@converse/skeletor/src/model.js';
-
-
-export default Model.extend({
-    defaults: {
-        "toggle-state":  _converse.OPENED
-    }
-});

+ 18 - 2
src/plugins/roomslist/templates/roomslist.js

@@ -1,5 +1,8 @@
-import { html } from "lit-html";
+import AddMUCModal from 'modals/add-muc.js';
+import MUCListModal from 'modals/muc-list.js';
 import { __ } from 'i18n';
+import { _converse, api } from "@converse/headless/core";
+import { html } from "lit-html";
 
 
 const bookmark = (o) => {
@@ -58,10 +61,23 @@ const room_item = (o) => {
 
 export default (o) => {
     const i18n_desc_rooms = __('Click to toggle the list of open groupchats');
+    const i18n_heading_chatrooms = __('Groupchats');
+    const i18n_title_list_rooms = __('Query for groupchats');
+    const i18n_title_new_room = __('Add a new groupchat');
     return html`
+        <div class="d-flex controlbox-padded">
+            <span class="w-100 controlbox-heading controlbox-heading--groupchats">${i18n_heading_chatrooms}</span>
+            <a class="controlbox-heading__btn show-list-muc-modal fa fa-list-ul"
+                @click=${(ev) => api.modal.show(MUCListModal, { 'model': o.model }, ev)}
+                title="${i18n_title_list_rooms}" data-toggle="modal" data-target="#muc-list-modal"></a>
+            <a class="controlbox-heading__btn show-add-muc-modal fa fa-plus"
+                @click=${(ev) => api.modal.show(AddMUCModal, { 'model': o.model }, ev)}
+                title="${i18n_title_new_room}" data-toggle="modal" data-target="#add-chatrooms-modal"></a>
+        </div>
+
         <div class="list-container list-container--openrooms ${ o.rooms.length ? '' : 'hidden' }">
             <a class="list-toggle open-rooms-toggle controlbox-padded" title="${i18n_desc_rooms}" @click=${o.toggleRoomsList}>
-            <span class="fa ${ (o.toggle_state === o._converse.OPENED) ? 'fa-caret-down' : 'fa-caret-right' }"></span> ${__('Open Groupchats')}</a>
+            <span class="fa ${ (o.toggle_state === _converse.OPENED) ? 'fa-caret-down' : 'fa-caret-right' }"></span> ${__('Open Groupchats')}</a>
             <div class="items-list rooms-list open-rooms-list ${ o.collapsed && 'collapsed' }">
                 ${ o.rooms.map(room => room_item(Object.assign({room}, o))) }
             </div>

+ 40 - 19
src/plugins/roomslist/view.js

@@ -1,26 +1,47 @@
 import RoomDetailsModal from 'modals/muc-details.js';
 import tpl_rooms_list from "./templates/roomslist.js";
 import { ElementView } from '@converse/skeletor/src/element.js';
+import { Model } from '@converse/skeletor/src/model.js';
 import { __ } from 'i18n';
 import { _converse, api, converse } from "@converse/headless/core";
+import { render } from 'lit-html';
 
 const { Strophe } = converse.env;
 const u = converse.env.utils;
 
 
+const RoomsListModel = Model.extend({
+    defaults: function () {
+        return {
+            'muc_domain': api.settings.get('muc_domain'),
+            'nick': _converse.getDefaultMUCNickname(),
+            'toggle-state':  _converse.OPENED,
+        };
+    },
+
+    setDomain (jid) {
+        if (!api.settings.get('locked_muc_domain')) {
+            this.save('muc_domain', Strophe.getDomainFromJid(jid));
+        }
+    }
+});
+
+
 export class RoomsList extends ElementView {
 
     initialize () {
-        this.model = _converse.chatboxes;
-        this.listenTo(this.model, 'add', this.renderIfChatRoom)
-        this.listenTo(this.model, 'remove', this.renderIfChatRoom)
-        this.listenTo(this.model, 'destroy', this.renderIfChatRoom)
-        this.listenTo(this.model, 'change', this.renderIfRelevantChange)
-
-        const id = `converse.roomslist${_converse.bare_jid}`;
-        this.list_model = new _converse.RoomsList({id});
-        this.list_model.browserStorage = _converse.createStore(id);
-        this.list_model.fetch();
+        const id = `converse.roomspanel${_converse.bare_jid}`;
+        this.model = new (RoomsListModel.extend({
+            id,
+            'browserStorage': _converse.createStore(id)
+        }))();
+        this.model.fetch();
+
+        this.listenTo(_converse.chatboxes, 'add', this.renderIfChatRoom)
+        this.listenTo(_converse.chatboxes, 'remove', this.renderIfChatRoom)
+        this.listenTo(_converse.chatboxes, 'destroy', this.renderIfChatRoom)
+        this.listenTo(_converse.chatboxes, 'change', this.renderIfRelevantChange)
+
         this.render();
     }
 
@@ -36,21 +57,21 @@ export class RoomsList extends ElementView {
         }
     }
 
-    toHTML () {
-        return tpl_rooms_list({
-            '_converse': _converse,
+    render () {
+        render(tpl_rooms_list({
             'addBookmark': ev => this.addBookmark(ev),
             'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks,
             'closeRoom': ev => this.closeRoom(ev),
-            'collapsed': this.list_model.get('toggle-state') !== _converse.OPENED,
+            'collapsed': this.model.get('toggle-state') !== _converse.OPENED,
             'currently_open': room => _converse.isUniView() && !room.get('hidden'),
+            'model': this.model,
             'openRoom': ev => this.openRoom(ev),
             'removeBookmark': ev => this.removeBookmark(ev),
-            'rooms': this.model.filter(m => m.get('type') === _converse.CHATROOMS_TYPE),
+            'rooms': _converse.chatboxes.filter(m => m.get('type') === _converse.CHATROOMS_TYPE),
             'showRoomDetailsModal': ev => this.showRoomDetailsModal(ev),
             'toggleRoomsList': ev => this.toggleRoomsList(ev),
-            'toggle_state': this.list_model.get('toggle-state')
-        });
+            'toggle_state': this.model.get('toggle-state')
+        }), this);
     }
 
     showRoomDetailsModal (ev) { // eslint-disable-line class-methods-use-this
@@ -94,13 +115,13 @@ export class RoomsList extends ElementView {
         const icon_el = ev.target.matches('.fa') ? ev.target : ev.target.querySelector('.fa');
         if (icon_el.classList.contains("fa-caret-down")) {
             u.slideIn(this.el.querySelector('.open-rooms-list')).then(() => {
-                this.list_model.save({'toggle-state': _converse.CLOSED});
+                this.model.save({'toggle-state': _converse.CLOSED});
                 icon_el.classList.remove("fa-caret-down");
                 icon_el.classList.add("fa-caret-right");
             });
         } else {
             u.slideOut(this.el.querySelector('.open-rooms-list')).then(() => {
-                this.list_model.save({'toggle-state': _converse.OPENED});
+                this.model.save({'toggle-state': _converse.OPENED});
                 icon_el.classList.remove("fa-caret-right");
                 icon_el.classList.add("fa-caret-down");
             });

+ 0 - 10
src/templates/room_panel.js

@@ -1,10 +0,0 @@
-import { html } from "lit-html";
-
-export default (o) => html`
-    <div class="d-flex controlbox-padded">
-        <span class="w-100 controlbox-heading controlbox-heading--groupchats">${o.heading_chatrooms}</span>
-        <a class="controlbox-heading__btn show-list-muc-modal fa fa-list-ul" title="${o.title_list_rooms}" data-toggle="modal" data-target="#muc-list-modal"></a>
-        <a class="controlbox-heading__btn show-add-muc-modal fa fa-plus" title="${o.title_new_room}" data-toggle="modal" data-target="#add-chatrooms-modal"></a>
-    </div>
-    <div class="list-container list-container--openrooms hidden"></div>
-    <div class="list-container list-container--bookmarks hidden"></div>`;