diff --git a/src/plugins/roomslist/index.js b/src/plugins/roomslist/index.js
index 9a6f278823..7d9cc13fef 100644
--- a/src/plugins/roomslist/index.js
+++ b/src/plugins/roomslist/index.js
@@ -7,7 +7,7 @@
*/
import "@converse/headless/plugins/muc/index.js";
import './view.js';
-import { converse } from "@converse/headless";
+import { api, converse } from "@converse/headless";
converse.plugins.add('converse-roomslist', {
@@ -19,5 +19,9 @@ converse.plugins.add('converse-roomslist', {
"converse-bookmarks"
],
- initialize () { }
+ initialize () {
+ api.settings.extend({
+ 'muc_grouped_by_domain': false,
+ });
+ }
});
diff --git a/src/plugins/roomslist/model.js b/src/plugins/roomslist/model.js
index 587145d56a..b0d3d29d57 100644
--- a/src/plugins/roomslist/model.js
+++ b/src/plugins/roomslist/model.js
@@ -10,6 +10,7 @@ class RoomsListModel extends Model {
'muc_domain': api.settings.get('muc_domain'),
'nick': _converse.getDefaultMUCNickname(),
'toggle_state': _converse.OPENED,
+ 'collapsed_domains': [],
};
}
diff --git a/src/plugins/roomslist/templates/roomslist.js b/src/plugins/roomslist/templates/roomslist.js
index e20fc5276a..b1283c97d4 100644
--- a/src/plugins/roomslist/templates/roomslist.js
+++ b/src/plugins/roomslist/templates/roomslist.js
@@ -67,10 +67,44 @@ function tplRoomItem (el, room) {
`;
}
+function tplRoomDomainGroup (el, domain, rooms) {
+ const i18n_title = __('Click to hide these rooms');
+ const collapsed = el.model.get('collapsed_domains');
+ const is_collapsed = collapsed.includes(domain);
+ return html`
+
+
el.toggleDomainList(ev, domain)}>
+
+ ${domain}
+
+
+ ${ rooms.map(room => tplRoomItem(el, room)) }
+
+
`;
+}
+
export default (el) => {
const { chatboxes, CHATROOMS_TYPE, CLOSED } = _converse;
+ const group_by_domain = api.settings.get('muc_grouped_by_domain');
const rooms = chatboxes.filter(m => m.get('type') === CHATROOMS_TYPE);
rooms.sort((a, b) => (a.getDisplayName().toLowerCase() <= b.getDisplayName().toLowerCase() ? -1 : 1));
+ // The rooms should stay sorted as they are iterated and added in order
+ const grouped_rooms = new Map();
+ if (group_by_domain) {
+ for (const room of rooms) {
+ const roomdomain = room.get('jid').split('@').at(-1).toLowerCase();
+ if (grouped_rooms.has(roomdomain)) {
+ grouped_rooms.get(roomdomain).push(room);
+ } else {
+ grouped_rooms.set(roomdomain, [room]);
+ }
+ }
+ }
+ const sorted_domains = Array.from(grouped_rooms.keys());
+ sorted_domains.sort();
const i18n_desc_rooms = __('Click to toggle the list of open groupchats');
const i18n_heading_chatrooms = __('Groupchats');
@@ -111,7 +145,10 @@ export default (el) => {
- ${ rooms.map(room => tplRoomItem(el, room)) }
+ ${ group_by_domain ?
+ sorted_domains.map(domain => tplRoomDomainGroup(el, domain, grouped_rooms.get(domain))) :
+ rooms.map(room => tplRoomItem(el, room))
+ }
`;
}
diff --git a/src/plugins/roomslist/view.js b/src/plugins/roomslist/view.js
index e0a3f38e1a..8771c0fe12 100644
--- a/src/plugins/roomslist/view.js
+++ b/src/plugins/roomslist/view.js
@@ -79,6 +79,16 @@ export class RoomsList extends CustomElement {
u.slideIn(list_el).then(() => this.model.save({'toggle_state': _converse.CLOSED}));
}
}
+
+ toggleDomainList (ev, domain) {
+ ev?.preventDefault?.();
+ const collapsed = this.model.get('collapsed_domains');
+ if (collapsed.includes(domain)) {
+ this.model.save({'collapsed_domains': collapsed.filter(d => d !== domain)});
+ } else {
+ this.model.save({'collapsed_domains': [...collapsed, domain]});
+ }
+ }
}
api.elements.define('converse-rooms-list', RoomsList);