-
-
Notifications
You must be signed in to change notification settings - Fork 776
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add option to group MUCs by their domain using collapsible lists * Document muc_grouped_by_domain * Add this change to CHANGES.md * Move muc domain group functions to their own file * Don’t use muc-domain-group class for distinct things This template was done in a similar way to rosterview’s group.js template, which uses the "roster-group" class for the group, and "roster-group-contacts" for the list. This commit changes MUC domain groups to use the "muc-domain-group" class for the group, and "muc-domain-group-rooms" for the list. * Attempt to add tests for MUC domain groups * Don’t focus MUC domain group tests * Fix focused test from master This allows CI tests to run properly on this merge request. It can be skipped if it’s fixed somewhere else on master first. * Add MUC domain group scss, attempting consistency with roster groups * Don’t use !important for MUC group headers Unlike(?) group-toggle (roster-groups) and open-rooms-toggle, it doesn’t seem necessary for the color to show.
- Loading branch information
Showing
11 changed files
with
205 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.conversejs { | ||
#chatrooms { | ||
.muc-domain-group-toggle { | ||
margin: 0.75em 0 0.25em 0; | ||
} | ||
|
||
.muc-domain-group-toggle, .muc-domain-group-toggle .fa { | ||
color: var(--groupchats-header-color); | ||
&:hover { | ||
color: var(--chatroom-head-bg-color-dark); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { __ } from 'i18n'; | ||
import { html } from "lit"; | ||
import { tplRoomItem } from 'plugins/roomslist/templates/roomslist.js' | ||
|
||
import '../styles/roomsgroups.scss'; | ||
|
||
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` | ||
<div class="muc-domain-group" data-domain="${domain}"> | ||
<a href="#" class="list-toggle muc-domain-group-toggle controlbox-padded" title="${i18n_title}" @click=${ev => el.toggleDomainList(ev, domain)}> | ||
<converse-icon | ||
class="fa ${ is_collapsed ? 'fa-caret-right' : 'fa-caret-down' }" | ||
size="1em" | ||
color="var(--groupchats-header-color)"></converse-icon> | ||
${domain} | ||
</a> | ||
<ul class="items-list muc-domain-group-rooms ${ is_collapsed ? 'collapsed' : '' }" data-domain="${domain}"> | ||
${ rooms.map(room => tplRoomItem(el, room)) } | ||
</ul> | ||
</div>`; | ||
} | ||
|
||
export function tplRoomDomainGroupList (el, rooms) { | ||
// The rooms should stay sorted as they are iterated and added in order | ||
const grouped_rooms = new Map(); | ||
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(); | ||
|
||
return sorted_domains.map(domain => tplRoomDomainGroup(el, domain, grouped_rooms.get(domain))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* global mock, converse */ | ||
|
||
const { $msg, u } = converse.env; | ||
|
||
|
||
describe("The list of MUC domains", function () { | ||
it("is shown in controlbox", mock.initConverse( | ||
['chatBoxesFetched'], | ||
{ muc_grouped_by_domain: true, | ||
allow_bookmarks: false // Makes testing easier, otherwise we | ||
// have to mock stanza traffic. | ||
}, async function (_converse) { | ||
|
||
await mock.waitForRoster(_converse, 'current', 0); | ||
await mock.openControlBox(_converse); | ||
const controlbox = _converse.chatboxviews.get('controlbox'); | ||
let list = controlbox.querySelector('.list-container--openrooms'); | ||
expect(u.hasClass('hidden', list)).toBeTruthy(); | ||
await mock.openChatRoom(_converse, 'room', 'conference.shakespeare.lit', 'JC'); | ||
|
||
const lview = controlbox.querySelector('converse-rooms-list'); | ||
// Check that the group is shown | ||
await u.waitUntil(() => lview.querySelectorAll(".muc-domain-group").length); | ||
let group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(1); | ||
// .children[0] should give the a tag with the domain in it | ||
// there might be a more robust way to do this | ||
// (select for ".muc-domain-group-toggle"?) | ||
// .trim() because there is a space for the arrow/triangle icon first | ||
expect(group_els[0].children[0].innerText.trim()).toBe('conference.shakespeare.lit'); | ||
// Check that the room is shown | ||
await u.waitUntil(() => lview.querySelectorAll(".open-room").length); | ||
let room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(1); | ||
expect(room_els[0].innerText).toBe('room@conference.shakespeare.lit'); | ||
|
||
// Check that a second room in the same domain is shown in the same | ||
// domain group. | ||
await mock.openChatRoom(_converse, 'secondroom', 'conference.shakespeare.lit', 'JC'); | ||
await u.waitUntil(() => lview.querySelectorAll(".open-room").length > 1); | ||
group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(1); // still only one group | ||
expect(group_els[0].children[0].innerText.trim()).toBe('conference.shakespeare.lit'); | ||
room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(2); // but two rooms inside it | ||
|
||
|
||
await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo'); | ||
await u.waitUntil(() => lview.querySelectorAll(".open-room").length > 2); | ||
room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(3); | ||
group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(2); | ||
|
||
let view = _converse.chatboxviews.get('room@conference.shakespeare.lit'); | ||
await view.close(); | ||
room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(2); | ||
group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(2); | ||
view = _converse.chatboxviews.get('secondroom@conference.shakespeare.lit'); | ||
await view.close(); | ||
room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(1); | ||
group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(1); | ||
expect(room_els[0].innerText).toBe('lounge@montague.lit'); | ||
expect(group_els[0].children[0].innerText.trim()).toBe('montague.lit'); | ||
list = controlbox.querySelector('.list-container--openrooms'); | ||
u.waitUntil(() => Array.from(list.classList).includes('hidden')); | ||
|
||
view = _converse.chatboxviews.get('lounge@montague.lit'); | ||
await view.close(); | ||
room_els = lview.querySelectorAll(".open-room"); | ||
expect(room_els.length).toBe(0); | ||
group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(0); | ||
|
||
list = controlbox.querySelector('.list-container--openrooms'); | ||
expect(Array.from(list.classList).includes('hidden')).toBeTruthy(); | ||
})); | ||
}); | ||
|
||
describe("A MUC domain group", function () { | ||
it("is collapsible", mock.initConverse( | ||
['chatBoxesFetched'], | ||
{ muc_grouped_by_domain: true, | ||
allow_bookmarks: false // Makes testing easier, otherwise we | ||
// have to mock stanza traffic. | ||
}, async function (_converse) { | ||
|
||
await mock.waitForRoster(_converse, 'current', 0); | ||
await mock.openControlBox(_converse); | ||
const controlbox = _converse.chatboxviews.get('controlbox'); | ||
let list = controlbox.querySelector('.list-container--openrooms'); | ||
await mock.openChatRoom(_converse, 'room', 'conference.shakespeare.lit', 'JC'); | ||
|
||
const lview = controlbox.querySelector('converse-rooms-list'); | ||
await u.waitUntil(() => lview.querySelectorAll(".muc-domain-group").length); | ||
expect(u.hasClass('hidden', list)).toBeFalsy(); | ||
let group_els = lview.querySelectorAll(".muc-domain-group"); | ||
expect(group_els.length).toBe(1); | ||
expect(group_els[0].children[0].innerText.trim()).toBe('conference.shakespeare.lit'); | ||
|
||
// I would have liked to use u.isVisible on the room (.open-room) here, | ||
// but it didn’t seem to work. | ||
expect(u.hasClass('collapsed', lview.querySelector(".muc-domain-group-rooms"))).toBe(false); | ||
lview.querySelector('.muc-domain-group-toggle').click(); | ||
await u.waitUntil(() => u.hasClass('collapsed', lview.querySelector(".muc-domain-group-rooms")) === true); | ||
expect(u.hasClass('collapsed', lview.querySelector(".muc-domain-group-rooms"))).toBe(true); | ||
lview.querySelector('.muc-domain-group-toggle').click(); | ||
await u.waitUntil(() => u.hasClass('collapsed', lview.querySelector(".muc-domain-group-rooms")) === false); | ||
expect(u.hasClass('collapsed', lview.querySelector(".muc-domain-group-rooms"))).toBe(false); | ||
})); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters