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} + + +
`; +} + 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);