Commit c41bdac6 authored by JC Brand's avatar JC Brand

Some work on componentizing the minimized chats UI

parent d5c93eb0
......@@ -3199,7 +3199,8 @@
"dependencies": {
"filesize": {
"version": "6.1.0",
"resolved": false
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
"integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg=="
},
"fs-extra": {
"version": "8.1.0",
......@@ -3233,7 +3234,8 @@
},
"jed": {
"version": "1.1.1",
"resolved": false
"resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
"integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ="
},
"jsonfile": {
"version": "5.0.0",
......@@ -3254,7 +3256,8 @@
},
"localforage": {
"version": "1.7.3",
"resolved": false,
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz",
"integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==",
"requires": {
"lie": "3.1.1"
}
......@@ -3266,13 +3269,14 @@
},
"pluggable.js": {
"version": "2.0.1",
"resolved": false,
"resolved": "https://registry.npmjs.org/pluggable.js/-/pluggable.js-2.0.1.tgz",
"integrity": "sha512-SBt6v6Tbp20Jf8hU0cpcc/+HBHGMY8/Q+yA6Ih0tBQE8tfdZ6U4PRG0iNvUUjLx/hVyOP53n0UfGBymlfaaXCg==",
"requires": {
"lodash": "^4.17.11"
}
},
"skeletor.js": {
"version": "0.0.1",
"version": "github:skeletorjs/skeletor#bf6d9c86f9fcf224fa9d9af5a25380b77aa4b561",
"from": "github:skeletorjs/skeletor#bf6d9c86f9fcf224fa9d9af5a25380b77aa4b561",
"requires": {
"lodash": "^4.17.14"
......@@ -3280,7 +3284,11 @@
},
"strophe.js": {
"version": "github:strophe/strophejs#c4a94e59877c06dc2395f4ccbd26f3fee67a4c9f",
"from": "strophe.js@github:strophe/strophejs#c4a94e59877c06dc2395f4ccbd26f3fee67a4c9f"
"from": "strophe.js@github:strophe/strophejs#c4a94e59877c06dc2395f4ccbd26f3fee67a4c9f",
"requires": {
"abab": "^2.0.3",
"xmldom": "^0.1.27"
}
},
"twemoji": {
"version": "12.1.5",
......
This diff is collapsed.
......@@ -700,68 +700,6 @@ describe("A Chat Message", function () {
done();
}));
it("received for a minimized chat box will increment a counter on its header",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
if (_converse.view_mode === 'fullscreen') {
return done();
}
await mock.waitForRoster(_converse, 'current');
const contact_name = mock.cur_names[0];
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
await mock.openControlBox(_converse);
spyOn(_converse.api, "trigger").and.callThrough();
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await mock.openChatBoxFor(_converse, contact_jid);
const chatview = _converse.api.chatviews.get(contact_jid);
expect(u.isVisible(chatview.el)).toBeTruthy();
expect(chatview.model.get('minimized')).toBeFalsy();
chatview.el.querySelector('.toggle-chatbox-button').click();
expect(chatview.model.get('minimized')).toBeTruthy();
var message = 'This message is sent to a minimized chatbox';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
var msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: u.getUniqueId()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.handleMessageStanza(msg);
await u.waitUntil(() => chatview.model.messages.length);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
const trimmed_chatboxes = _converse.minimized_chats;
const trimmedview = trimmed_chatboxes.get(contact_jid);
let count = trimmedview.el.querySelector('.message-count');
expect(u.isVisible(chatview.el)).toBeFalsy();
expect(trimmedview.model.get('minimized')).toBeTruthy();
expect(u.isVisible(count)).toBeTruthy();
expect(count.textContent).toBe('1');
_converse.handleMessageStanza(
$msg({
from: mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
to: _converse.connection.jid,
type: 'chat',
id: u.getUniqueId()
}).c('body').t('This message is also sent to a minimized chatbox').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
);
await u.waitUntil(() => (chatview.model.messages.length > 1));
expect(u.isVisible(chatview.el)).toBeFalsy();
expect(trimmedview.model.get('minimized')).toBeTruthy();
count = trimmedview.el.querySelector('.message-count');
expect(u.isVisible(count)).toBeTruthy();
expect(count.textContent).toBe('2');
trimmedview.el.querySelector('.restore-chat').click();
expect(trimmed_chatboxes.keys().length).toBe(0);
done();
}));
it("will indicate when it has a time difference of more than a day between it and its predecessor",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
......
This diff is collapsed.
......@@ -2862,38 +2862,6 @@ describe("Groupchats", function () {
done();
}));
it("can be minimized by clicking a DOM element with class 'toggle-chatbox-button'",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'),
trimmed_chatboxes = _converse.minimized_chats;
spyOn(view, 'onMinimized').and.callThrough();
spyOn(view, 'onMaximized').and.callThrough();
spyOn(_converse.api, "trigger").and.callThrough();
view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
const button = await u.waitUntil(() => view.el.querySelector('.toggle-chatbox-button'));
button.click();
expect(view.onMinimized).toHaveBeenCalled();
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxMinimized', jasmine.any(Object));
expect(u.isVisible(view.el)).toBeFalsy();
expect(view.model.get('minimized')).toBeTruthy();
expect(view.onMinimized).toHaveBeenCalled();
await u.waitUntil(() => trimmed_chatboxes.get(view.model.get('id')));
const trimmedview = trimmed_chatboxes.get(view.model.get('id'));
trimmedview.el.querySelector("a.restore-chat").click();
expect(view.onMaximized).toHaveBeenCalled();
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxMaximized', jasmine.any(Object));
expect(view.model.get('minimized')).toBeFalsy();
expect(_converse.api.trigger.calls.count(), 3);
done();
}));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
......
import { CustomElement } from './element.js';
import tpl_trimmed_chat from "templates/trimmed_chat.js";
import { api, _converse } from "@converse/headless/converse-core";
export default class MinimizedChat extends CustomElement {
static get properties () {
return {
model: { type: Object },
title: { type: String },
type: { type: String },
num_unread: { type: Number }
}
}
render () {
const data = {
'close': ev => this.close(ev),
'num_unread': this.num_unread,
'restore': ev => this.restore(ev),
'title': this.title,
'type': this.type
};
return tpl_trimmed_chat(data);
}
close (ev) {
ev?.preventDefault();
const view = _converse.chatboxviews.get(this.model.get('id'));
if (view) {
// This will call model.destroy(), removing it from the
// collection and will also emit 'chatBoxClosed'
view.close();
} else {
this.model.destroy();
api.trigger('chatBoxClosed', this);
}
}
restore (ev) {
ev?.preventDefault();
this.model.maximize();
}
}
api.elements.define('converse-minimized-chat', MinimizedChat);
This diff is collapsed.
<a id="toggle-minimized-chats" href="#" class="row no-gutters"></a>
<div class="flyout minimized-chats-flyout row no-gutters"></div>
import { html } from "lit-html";
import { __ } from '@converse/headless/i18n';
export default (o) =>
html`<div id="minimized-chats" class="${o.chats.length ? '' : 'hidden'}">
<a id="toggle-minimized-chats" class="row no-gutters" @click=${o.toggle}>
${o.num_minimized} ${__('Minimized')}
<span class="unread-message-count ${!o.num_unread ? 'unread-message-count-hidden' : ''}" href="#">${o.num_unread}</span>
</a>
<div class="flyout minimized-chats-flyout row no-gutters ${o.collapsed ? 'hidden' : ''}">
${o.chats.map(chat =>
html`<converse-minimized-chat
.model=${chat}
title=${chat.getDisplayName()}
type=${chat.get('type')}
num_unread=${chat.get('num_unread')}></converse-minimized-chat>`)}
</div>
</div>`;
import { html } from "lit-html";
import { __ } from '@converse/headless/i18n';
export default (o) => html`
${o.num_minimized} ${__('Minimized')}
<span class="unread-message-count ${!o.num_unread ? 'unread-message-count-hidden' : ''}" href="#">${o.num_unread}</span>
`;
......@@ -6,10 +6,10 @@ export default (o) => {
const i18n_tooltip = __('Click to restore this chat');
return html`
<div class="chat-head-${o.type} chat-head row no-gutters">
<a class="restore-chat w-100 align-self-center" title="${i18n_tooltip}">
<a class="restore-chat w-100 align-self-center" title="${i18n_tooltip}" @click=${o.restore}>
${o.num_unread ? html`<span class="message-count badge badge-light">${o.num_unread}</span>` : '' }
${o.title}
</a>
<a class="chatbox-btn close-chatbox-button fa fa-times"></a>
<a class="chatbox-btn close-chatbox-button fa fa-times" @click=${o.close}></a>
</div>`;
}
......@@ -20,6 +20,7 @@
}
});
converse.initialize({
// root: new DocumentFragment(),
show_send_button: true,
auto_away: 300,
auto_register_muc_nickname: true,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment