Create converse-muc-chatarea
component
This commit is contained in:
parent
4fd848ff3e
commit
4ca30c4b93
@ -140,6 +140,13 @@
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
converse-muc-chatarea {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: nowrap;
|
||||
}
|
||||
|
||||
.row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ describe("Chatboxes", function () {
|
||||
id: u.getUniqueId()
|
||||
}).c('body').t('hello world').tree();
|
||||
await _converse.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
const msg_txt_sel = 'converse-chat-message:last-child .chat-msg__body';
|
||||
await u.waitUntil(() => view.querySelector(msg_txt_sel).textContent.trim() === 'hello world');
|
||||
done();
|
||||
@ -524,7 +524,7 @@ describe("Chatboxes", function () {
|
||||
id: u.getUniqueId()
|
||||
}).c('body').t('hello world').tree();
|
||||
await _converse.handleMessageStanza(msg);
|
||||
const msg_el = await u.waitUntil(() => view.content.querySelector('.chat-msg'));
|
||||
const msg_el = await u.waitUntil(() => view.querySelector('.chat-msg'));
|
||||
await u.waitUntil( () => view.querySelector('.chat-content__notifications').innerText === '');
|
||||
expect(msg_el.querySelector('.chat-msg__text').textContent).toBe('hello world');
|
||||
done();
|
||||
|
@ -267,7 +267,7 @@ describe("Emojis", function () {
|
||||
await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.content.querySelector('.chat-msg__text')));
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.querySelector('.chat-msg__text')));
|
||||
|
||||
_converse.handleMessageStanza($msg({
|
||||
'from': sender_jid,
|
||||
@ -279,7 +279,7 @@ describe("Emojis", function () {
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
|
||||
|
||||
let sel = '.message:last-child .chat-msg__text';
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.content.querySelector(sel)));
|
||||
await u.waitUntil(() => u.hasClass('chat-msg__text--larger', view.querySelector(sel)));
|
||||
|
||||
// Test that a modified message that no longer contains only
|
||||
// emojis now renders normally again.
|
||||
@ -293,7 +293,7 @@ describe("Emojis", function () {
|
||||
});
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
|
||||
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
|
||||
await u.waitUntil(() => view.content.querySelector(last_msg_sel).textContent === '💩 😇');
|
||||
await u.waitUntil(() => view.querySelector(last_msg_sel).textContent === '💩 😇');
|
||||
|
||||
expect(textarea.value).toBe('');
|
||||
bottom_panel.onKeyDown({
|
||||
@ -314,7 +314,7 @@ describe("Emojis", function () {
|
||||
await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-msg__text'))
|
||||
.filter(el => el.textContent === edited_text).length);
|
||||
expect(view.model.messages.models.length).toBe(3);
|
||||
let message = view.content.querySelector(last_msg_sel);
|
||||
let message = view.querySelector(last_msg_sel);
|
||||
expect(u.hasClass('chat-msg__text--larger', message)).toBe(false);
|
||||
|
||||
textarea.value = ':smile: Hello world!';
|
||||
@ -333,7 +333,7 @@ describe("Emojis", function () {
|
||||
});
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 5);
|
||||
|
||||
message = view.content.querySelector('.message:last-child .chat-msg__text');
|
||||
message = view.querySelector('.message:last-child .chat-msg__text');
|
||||
expect(u.hasClass('chat-msg__text--larger', message)).toBe(true);
|
||||
done()
|
||||
}));
|
||||
@ -355,11 +355,11 @@ describe("Emojis", function () {
|
||||
await new Promise(resolve => _converse.on('chatBoxViewInitialized', resolve));
|
||||
const view = _converse.api.chatviews.get(contact_jid);
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
await u.waitUntil(() => view.content.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '') ===
|
||||
await u.waitUntil(() => view.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '') ===
|
||||
'<img class="emoji" draggable="false" title=":innocent:" alt="😇" src="https://twemoji.maxcdn.com/v/12.1.6//72x72/1f607.png">');
|
||||
|
||||
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
|
||||
let message = view.content.querySelector(last_msg_sel);
|
||||
let message = view.querySelector(last_msg_sel);
|
||||
await u.waitUntil(() => u.isVisible(message.querySelector('.emoji')), 1000);
|
||||
let imgs = message.querySelectorAll('.emoji');
|
||||
expect(imgs.length).toBe(1);
|
||||
@ -374,7 +374,7 @@ describe("Emojis", function () {
|
||||
keyCode: 13 // Enter
|
||||
});
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
message = view.content.querySelector(last_msg_sel);
|
||||
message = view.querySelector(last_msg_sel);
|
||||
await u.waitUntil(() => u.isVisible(message.querySelector('.emoji')), 1000);
|
||||
imgs = message.querySelectorAll('.emoji');
|
||||
expect(imgs.length).toBe(2);
|
||||
|
18
spec/mam.js
18
spec/mam.js
@ -267,8 +267,8 @@ describe("Message Archive Management", function () {
|
||||
</iq>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
await u.waitUntil(() => view.model.messages.length === 5);
|
||||
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg__text').length);
|
||||
await u.waitUntil(() => Array.from(view.content.querySelectorAll('.chat-msg__text'))
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
|
||||
await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-msg__text'))
|
||||
.map(e => e.textContent).join(' ') === "2nd Message 3rd Message 4th Message 5th Message 6th Message", 1000);
|
||||
done();
|
||||
}));
|
||||
@ -455,7 +455,7 @@ describe("Message Archive Management", function () {
|
||||
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
expect(view.model.messages.at(0).get('is_archived')).toBe(false);
|
||||
expect(view.model.messages.at(0).get('stanza_id trek-radio@conference.lightwitch.org')).toBe('45fbbf2a-1059-479d-9283-c8effaf05621');
|
||||
@ -480,7 +480,7 @@ describe("Message Archive Management", function () {
|
||||
expect(view.model.getDuplicateMessage.calls.count()).toBe(1);
|
||||
const result = view.model.getDuplicateMessage.calls.all()[0].returnValue
|
||||
expect(result instanceof _converse.Message).toBe(true);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
|
||||
await u.waitUntil(() => view.model.updateMessage.calls.count());
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
@ -502,7 +502,7 @@ describe("Message Archive Management", function () {
|
||||
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
// Not sure whether such a race-condition might pose a problem
|
||||
// in "real-world" situations.
|
||||
stanza = u.toStanza(
|
||||
@ -524,7 +524,7 @@ describe("Message Archive Management", function () {
|
||||
expect(view.model.getDuplicateMessage.calls.count()).toBe(1);
|
||||
const result = await view.model.getDuplicateMessage.calls.all()[0].returnValue
|
||||
expect(result instanceof _converse.Message).toBe(true);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -550,8 +550,8 @@ describe("Message Archive Management", function () {
|
||||
</result>
|
||||
</message>`);
|
||||
_converse.handleMAMResult(view.model, { 'messages': [stanza] });
|
||||
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
|
||||
stanza = u.toStanza(
|
||||
`<message xmlns="jabber:client" to="romeo@montague.lit/orchard" from="discuss@conference.conversejs.org">
|
||||
@ -574,7 +574,7 @@ describe("Message Archive Management", function () {
|
||||
expect(view.model.getDuplicateMessage.calls.count()).toBe(1);
|
||||
const result = await view.model.getDuplicateMessage.calls.all()[0].returnValue
|
||||
expect(result instanceof _converse.Message).toBe(true);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
done();
|
||||
}))
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ describe("A Groupchat Message", function () {
|
||||
'type': 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => sizzle('.chat-msg:last .chat-msg__text', view.content).pop());
|
||||
await u.waitUntil(() => sizzle('.chat-msg:last .chat-msg__text', view).pop());
|
||||
await u.waitUntil(() => view.querySelector('.chat-msg__text').textContent.trim() === 'is tired');
|
||||
expect(view.querySelector('.chat-msg__author').textContent.includes('**Dyon van de Wege')).toBeTruthy();
|
||||
|
||||
|
@ -381,7 +381,7 @@ describe("A sent groupchat message", function () {
|
||||
|
||||
const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text';
|
||||
await u.waitUntil(() =>
|
||||
view.content.querySelector(last_msg_sel).innerHTML.replace(/<!---->/g, '') ===
|
||||
view.querySelector(last_msg_sel).innerHTML.replace(/<!---->/g, '') ===
|
||||
'hello <span class="mention">z3r0</span> <span class="mention">gibson</span> <span class="mention">mr.robot</span>, how are you?'
|
||||
);
|
||||
|
||||
|
164
spec/messages.js
164
spec/messages.js
@ -190,53 +190,53 @@ describe("A Chat Message", function () {
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length === 7);
|
||||
|
||||
view.clearSpinner(); //cleanup
|
||||
expect(view.content.querySelectorAll('.date-separator').length).toEqual(4);
|
||||
expect(view.querySelectorAll('.date-separator').length).toEqual(4);
|
||||
|
||||
let day = sizzle('.date-separator:first', view.content).pop();
|
||||
let day = sizzle('.date-separator:first', view).pop();
|
||||
expect(day.getAttribute('data-isodate')).toEqual(dayjs('2017-12-31T00:00:00').toISOString());
|
||||
|
||||
let time = sizzle('time:first', view.content).pop();
|
||||
let time = sizzle('time:first', view).pop();
|
||||
expect(time.textContent).toEqual('Sunday Dec 31st 2017')
|
||||
|
||||
day = sizzle('.date-separator:first', view.content).pop();
|
||||
day = sizzle('.date-separator:first', view).pop();
|
||||
expect(day.nextElementSibling.querySelector('.chat-msg__text').textContent).toBe('Older message');
|
||||
|
||||
let el = sizzle('.chat-msg:first', view.content).pop().querySelector('.chat-msg__text')
|
||||
let el = sizzle('.chat-msg:first', view).pop().querySelector('.chat-msg__text')
|
||||
expect(u.hasClass('chat-msg--followup', el)).toBe(false);
|
||||
expect(el.textContent).toEqual('Older message');
|
||||
|
||||
time = sizzle('time.separator-text:eq(1)', view.content).pop();
|
||||
time = sizzle('time.separator-text:eq(1)', view).pop();
|
||||
expect(time.textContent).toEqual("Monday Jan 1st 2018");
|
||||
|
||||
day = sizzle('.date-separator:eq(1)', view.content).pop();
|
||||
day = sizzle('.date-separator:eq(1)', view).pop();
|
||||
expect(day.getAttribute('data-isodate')).toEqual(dayjs('2018-01-01T00:00:00').toISOString());
|
||||
expect(day.nextElementSibling.querySelector('.chat-msg__text').textContent).toBe('Inbetween message');
|
||||
|
||||
el = sizzle('.chat-msg:eq(1)', view.content).pop();
|
||||
el = sizzle('.chat-msg:eq(1)', view).pop();
|
||||
expect(el.querySelector('.chat-msg__text').textContent).toEqual('Inbetween message');
|
||||
expect(el.parentElement.nextElementSibling.querySelector('.chat-msg__text').textContent).toEqual('another inbetween message');
|
||||
el = sizzle('.chat-msg:eq(2)', view.content).pop();
|
||||
el = sizzle('.chat-msg:eq(2)', view).pop();
|
||||
expect(el.querySelector('.chat-msg__text').textContent)
|
||||
.toEqual('another inbetween message');
|
||||
expect(u.hasClass('chat-msg--followup', el)).toBe(true);
|
||||
|
||||
time = sizzle('time.separator-text:nth(2)', view.content).pop();
|
||||
time = sizzle('time.separator-text:nth(2)', view).pop();
|
||||
expect(time.textContent).toEqual("Tuesday Jan 2nd 2018");
|
||||
|
||||
day = sizzle('.date-separator:nth(2)', view.content).pop();
|
||||
day = sizzle('.date-separator:nth(2)', view).pop();
|
||||
expect(day.getAttribute('data-isodate')).toEqual(dayjs('2018-01-02T00:00:00').toISOString());
|
||||
expect(day.nextElementSibling.querySelector('.chat-msg__text').textContent).toBe('An earlier message on the next day');
|
||||
|
||||
el = sizzle('.chat-msg:eq(3)', view.content).pop();
|
||||
el = sizzle('.chat-msg:eq(3)', view).pop();
|
||||
expect(el.querySelector('.chat-msg__text').textContent).toEqual('An earlier message on the next day');
|
||||
expect(u.hasClass('chat-msg--followup', el)).toBe(false);
|
||||
|
||||
el = sizzle('.chat-msg:eq(4)', view.content).pop();
|
||||
el = sizzle('.chat-msg:eq(4)', view).pop();
|
||||
expect(el.querySelector('.chat-msg__text').textContent).toEqual('message');
|
||||
expect(el.parentElement.nextElementSibling.querySelector('.chat-msg__text').textContent).toEqual('newer message from the next day');
|
||||
expect(u.hasClass('chat-msg--followup', el)).toBe(false);
|
||||
|
||||
day = sizzle('.date-separator:last', view.content).pop();
|
||||
day = sizzle('.date-separator:last', view).pop();
|
||||
expect(day.getAttribute('data-isodate')).toEqual(dayjs().startOf('day').toISOString());
|
||||
expect(day.nextElementSibling.querySelector('.chat-msg__text').textContent).toBe('latest message');
|
||||
expect(u.hasClass('chat-msg--followup', el)).toBe(false);
|
||||
@ -310,12 +310,12 @@ describe("A Chat Message", function () {
|
||||
expect(msg_obj.get('sender')).toEqual('them');
|
||||
expect(msg_obj.get('is_delayed')).toEqual(false);
|
||||
// Now check that the message appears inside the chatbox in the DOM
|
||||
await u.waitUntil(() => view.content.querySelector('.chat-msg .chat-msg__text'));
|
||||
await u.waitUntil(() => view.querySelector('.chat-msg .chat-msg__text'));
|
||||
|
||||
expect(view.content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(msgtext);
|
||||
expect(view.content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
expect(view.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(msgtext);
|
||||
expect(view.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
await u.waitUntil(() => chatbox.vcard.get('fullname') === 'Juliet Capulet')
|
||||
expect(view.content.querySelector('span.chat-msg__author').textContent.trim()).toBe('Juliet Capulet');
|
||||
expect(view.querySelector('span.chat-msg__author').textContent.trim()).toBe('Juliet Capulet');
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -578,7 +578,7 @@ describe("A Chat Message", function () {
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
|
||||
expect(view.content.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard the news?');
|
||||
expect(view.querySelector('.chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard the news?');
|
||||
stanza = u.toStanza(`
|
||||
<message from="${contact_jid}"
|
||||
type="chat"
|
||||
@ -587,7 +587,7 @@ describe("A Chat Message", function () {
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 2);
|
||||
const text = view.content.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
|
||||
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
|
||||
expect(text).toBe('Hey\n\u200B\nHave you heard the news?');
|
||||
stanza = u.toStanza(`
|
||||
<message from="${contact_jid}"
|
||||
@ -597,7 +597,7 @@ describe("A Chat Message", function () {
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 3);
|
||||
expect(view.content.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard\nthe news?');
|
||||
expect(view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '')).toBe('Hey\nHave you heard\nthe news?');
|
||||
|
||||
stanza = u.toStanza(`
|
||||
<message from="${contact_jid}"
|
||||
@ -608,7 +608,7 @@ describe("A Chat Message", function () {
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 4);
|
||||
await u.waitUntil(() => {
|
||||
const text = view.content.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
|
||||
const text = view.querySelector('converse-chat-message:last-child .chat-msg__text').innerHTML.replace(/<!---->/g, '');
|
||||
return text === 'Hey\nHave you heard\n\u200B\nthe news?\n<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>';
|
||||
});
|
||||
done();
|
||||
@ -655,7 +655,7 @@ describe("A Chat Message", function () {
|
||||
message = 'https://imgur.com/oxymPax';
|
||||
await mock.sendMessage(view, message);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-image').length === 5, 1000);
|
||||
expect(view.content.querySelectorAll('.chat-content .chat-image').length).toBe(5);
|
||||
expect(view.querySelectorAll('.chat-content .chat-image').length).toBe(5);
|
||||
|
||||
// Check that the Imgur URL gets a .png attached to make it render
|
||||
await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-content .chat-image')).pop().src.endsWith('png'), 1000);
|
||||
@ -681,7 +681,7 @@ describe("A Chat Message", function () {
|
||||
await mock.sendMessage(view, message);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-msg').length === 2, 1000);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-image').length === 1, 1000)
|
||||
expect(view.content.querySelectorAll('.chat-content .chat-image').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-content .chat-image').length).toBe(1);
|
||||
|
||||
done();
|
||||
}));
|
||||
@ -821,24 +821,24 @@ describe("A Chat Message", function () {
|
||||
jasmine.clock().tick(1*ONE_MINUTE_LATER);
|
||||
await mock.sendMessage(view, "Another message within 10 minutes, but from a different person");
|
||||
|
||||
expect(view.content.querySelectorAll('.message').length).toBe(6);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(5);
|
||||
expect(view.querySelectorAll('.message').length).toBe(6);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(5);
|
||||
|
||||
const nth_child = (n) => `converse-chat-message:nth-child(${n}) .chat-msg`;
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 3 minutes later");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(4)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(4)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 14 minutes since we started");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(5)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(5)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 1 minute and 1 second since the previous one");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(6)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(6)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message within 10 minutes, but from a different person");
|
||||
|
||||
// Let's add a delayed, inbetween message
|
||||
@ -854,29 +854,29 @@ describe("A Chat Message", function () {
|
||||
.tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
expect(view.content.querySelectorAll('.message').length).toBe(7);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(6);
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
expect(view.querySelectorAll('.message').length).toBe(7);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(6);
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
|
||||
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 3 minutes later");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(4)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(4)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
"A delayed message, sent 5 minutes since we started");
|
||||
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(5)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(5)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 14 minutes since we started");
|
||||
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(6)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(6)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 1 minute and 1 second since the previous one");
|
||||
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(7)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(7)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(7)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(7)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message within 10 minutes, but from a different person");
|
||||
|
||||
_converse.handleMessageStanza(
|
||||
@ -891,26 +891,26 @@ describe("A Chat Message", function () {
|
||||
.tree());
|
||||
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
||||
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(7);
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(7);
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(2)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(2)} .chat-msg__text`).textContent).toBe("A message");
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(3)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(3)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 3 minutes later");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(4)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(4)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(4)} .chat-msg__text`).textContent).toBe(
|
||||
"A carbon message 4 minutes later");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(5)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(5)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(5)} .chat-msg__text`).textContent).toBe(
|
||||
"A delayed message, sent 5 minutes since we started");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(6)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(6)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(6)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 14 minutes since we started");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(7)))).toBe(true);
|
||||
expect(view.content.querySelector(`${nth_child(7)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(7)))).toBe(true);
|
||||
expect(view.querySelector(`${nth_child(7)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message 1 minute and 1 second since the previous one");
|
||||
expect(u.hasClass('chat-msg--followup', view.content.querySelector(nth_child(8)))).toBe(false);
|
||||
expect(view.content.querySelector(`${nth_child(8)} .chat-msg__text`).textContent).toBe(
|
||||
expect(u.hasClass('chat-msg--followup', view.querySelector(nth_child(8)))).toBe(false);
|
||||
expect(view.querySelector(`${nth_child(8)} .chat-msg__text`).textContent).toBe(
|
||||
"Another message within 10 minutes, but from a different person");
|
||||
|
||||
jasmine.clock().uninstall();
|
||||
@ -1000,11 +1000,11 @@ describe("A Chat Message", function () {
|
||||
expect(msg_obj.get('sender')).toEqual('them');
|
||||
expect(msg_obj.get('is_delayed')).toEqual(false);
|
||||
// Now check that the message appears inside the chatbox in the DOM
|
||||
const mel = await u.waitUntil(() => view.content.querySelector('.chat-msg .chat-msg__text'));
|
||||
const mel = await u.waitUntil(() => view.querySelector('.chat-msg .chat-msg__text'));
|
||||
expect(mel.textContent).toEqual(message);
|
||||
expect(view.content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
expect(view.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
await u.waitUntil(() => chatbox.vcard.get('fullname') === mock.cur_names[0]);
|
||||
expect(view.content.querySelector('span.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
||||
expect(view.querySelector('span.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -1030,7 +1030,7 @@ describe("A Chat Message", function () {
|
||||
expect(view.model.messages.length).toEqual(1);
|
||||
const msg_obj = view.model.messages.at(0);
|
||||
expect(msg_obj.get('message')).toEqual(message.trim());
|
||||
const mel = await u.waitUntil(() => view.content.querySelector('.chat-msg .chat-msg__text'));
|
||||
const mel = await u.waitUntil(() => view.querySelector('.chat-msg .chat-msg__text'));
|
||||
expect(mel.textContent).toEqual(message.trim());
|
||||
done();
|
||||
}));
|
||||
@ -1138,9 +1138,9 @@ describe("A Chat Message", function () {
|
||||
|
||||
await u.waitUntil(() => view.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
|
||||
// Now check that the message appears inside the chatbox in the DOM
|
||||
expect(view.content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(message);
|
||||
expect(view.content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
expect(view.content.querySelector('span.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
||||
expect(view.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(message);
|
||||
expect(view.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
|
||||
expect(view.querySelector('span.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
||||
done();
|
||||
}));
|
||||
});
|
||||
@ -1174,7 +1174,7 @@ describe("A Chat Message", function () {
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
const message = await view.model.sendMessage(msg_text);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
let msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
|
||||
let msg_txt = sizzle('.chat-msg:last .chat-msg__text', view).pop().textContent;
|
||||
expect(msg_txt).toEqual(msg_text);
|
||||
|
||||
// We send another message, for which an error will
|
||||
@ -1182,8 +1182,8 @@ describe("A Chat Message", function () {
|
||||
// after the relevant message.
|
||||
msg_text = 'This message will be sent, and also receive an error';
|
||||
const second_message = await view.model.sendMessage(msg_text);
|
||||
await u.waitUntil(() => sizzle('.chat-msg .chat-msg__text', view.content).length === 2, 1000);
|
||||
msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
|
||||
await u.waitUntil(() => sizzle('.chat-msg .chat-msg__text', view).length === 2, 1000);
|
||||
msg_txt = sizzle('.chat-msg:last .chat-msg__text', view).pop().textContent;
|
||||
expect(msg_txt).toEqual(msg_text);
|
||||
|
||||
/* <message xmlns="jabber:client"
|
||||
@ -1208,7 +1208,7 @@ describe("A Chat Message", function () {
|
||||
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
|
||||
.t('Server-to-server connection failed: Connecting failed: connection timeout');
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() => view.content.querySelector('.chat-msg__error').textContent.trim() === error_txt);
|
||||
await u.waitUntil(() => view.querySelector('.chat-msg__error').textContent.trim() === error_txt);
|
||||
|
||||
const other_error_txt = 'Server-to-server connection failed: Connecting failed: connection timeout';
|
||||
stanza = $msg({
|
||||
@ -1223,7 +1223,7 @@ describe("A Chat Message", function () {
|
||||
.t(other_error_txt);
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
await u.waitUntil(() =>
|
||||
view.content.querySelector('converse-chat-message:last-child .chat-msg__error').textContent.trim() === other_error_txt);
|
||||
view.querySelector('converse-chat-message:last-child .chat-msg__error').textContent.trim() === other_error_txt);
|
||||
|
||||
// We don't render duplicates
|
||||
stanza = $msg({
|
||||
@ -1237,11 +1237,11 @@ describe("A Chat Message", function () {
|
||||
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
|
||||
.t('Server-to-server connection failed: Connecting failed: connection timeout');
|
||||
_converse.connection._dataRecv(mock.createRequest(stanza));
|
||||
expect(view.content.querySelectorAll('.chat-msg__error').length).toEqual(2);
|
||||
expect(view.querySelectorAll('.chat-msg__error').length).toEqual(2);
|
||||
|
||||
msg_text = 'This message will be sent, and also receive an error';
|
||||
const third_message = await view.model.sendMessage(msg_text);
|
||||
await u.waitUntil(() => sizzle('converse-chat-message:last-child .chat-msg__text', view.content).pop()?.textContent === msg_text);
|
||||
await u.waitUntil(() => sizzle('converse-chat-message:last-child .chat-msg__text', view).pop()?.textContent === msg_text);
|
||||
|
||||
// A different error message will however render
|
||||
stanza = $msg({
|
||||
@ -1302,7 +1302,7 @@ describe("A Chat Message", function () {
|
||||
const msg_text = 'This message will show!';
|
||||
await view.model.sendMessage(msg_text);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
|
||||
expect(view.content.querySelectorAll('.chat-error').length).toEqual(0);
|
||||
expect(view.querySelectorAll('.chat-error').length).toEqual(0);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
@ -1317,7 +1317,7 @@ describe("A Chat Message", function () {
|
||||
const view = _converse.api.chatviews.get(sender_jid);
|
||||
// Create enough messages so that there's a scrollbar.
|
||||
const promises = [];
|
||||
view.content.scrollTop = 0;
|
||||
view.querySelector('.chat-content').scrollTop = 0;
|
||||
view.model.set('scrolled', true);
|
||||
|
||||
for (let i=0; i<20; i++) {
|
||||
@ -1336,7 +1336,7 @@ describe("A Chat Message", function () {
|
||||
expect(u.isVisible(indicator_el)).toBeTruthy();
|
||||
|
||||
expect(view.model.get('scrolled')).toBe(true);
|
||||
expect(view.content.scrollTop).toBe(0);
|
||||
expect(view.querySelector('.chat-content').scrollTop).toBe(0);
|
||||
indicator_el.click();
|
||||
expect(u.isVisible(indicator_el)).toBeFalsy();
|
||||
expect(view.model.get('scrolled')).toBe(false);
|
||||
|
42
spec/muc.js
42
spec/muc.js
@ -927,7 +927,7 @@ describe("Groupchats", function () {
|
||||
|
||||
const num_info_msgs = await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-info').length);
|
||||
expect(num_info_msgs).toBe(1);
|
||||
expect(sizzle('div.chat-info', view.content).pop().textContent.trim()).toBe("This groupchat is not anonymous");
|
||||
expect(sizzle('div.chat-info', view).pop().textContent.trim()).toBe("This groupchat is not anonymous");
|
||||
|
||||
const csntext = await u.waitUntil(() => view.querySelector('.chat-content__notifications').textContent);
|
||||
expect(csntext.trim()).toEqual("some1 has entered the groupchat");
|
||||
@ -1408,7 +1408,7 @@ describe("Groupchats", function () {
|
||||
}).c('body').t('Some message').tree();
|
||||
|
||||
await view.model.handleMessageStanza(msg);
|
||||
await u.waitUntil(() => sizzle('.chat-msg:last .chat-msg__text', view.content).pop());
|
||||
await u.waitUntil(() => sizzle('.chat-msg:last .chat-msg__text', view).pop());
|
||||
|
||||
let stanza = u.toStanza(
|
||||
`<presence xmlns="jabber:client" to="romeo@montague.lit/orchard" type="unavailable" from="conversations@conference.siacs.eu/Guus">
|
||||
@ -2089,8 +2089,8 @@ describe("Groupchats", function () {
|
||||
}).c('body').t(text);
|
||||
await view.model.handleMessageStanza(message.nodeTree);
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.content.querySelector('.chat-msg__text').textContent.trim()).toBe(text);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelector('.chat-msg__text').textContent.trim()).toBe(text);
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
done();
|
||||
}));
|
||||
@ -2111,7 +2111,7 @@ describe("Groupchats", function () {
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
|
||||
|
||||
expect(_converse.api.trigger).toHaveBeenCalledWith('messageSend', jasmine.any(_converse.Message));
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
|
||||
// Let's check that if we receive the same message again, it's
|
||||
// not shown.
|
||||
@ -2127,7 +2127,7 @@ describe("Groupchats", function () {
|
||||
<origin-id xmlns="urn:xmpp:sid:0" id="${view.model.messages.at(0).get('origin_id')}"/>
|
||||
</message>`);
|
||||
await view.model.handleMessageStanza(stanza);
|
||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(sizzle('.chat-msg__text:last').pop().textContent.trim()).toBe(text);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
// We don't emit an event if it's our own message
|
||||
@ -2158,7 +2158,8 @@ describe("Groupchats", function () {
|
||||
await Promise.all(promises);
|
||||
// Give enough time for `markScrolled` to have been called
|
||||
setTimeout(async () => {
|
||||
view.content.scrollTop = 0;
|
||||
const content = view.querySelector('.chat-content');
|
||||
content.scrollTop = 0;
|
||||
await view.model.handleMessageStanza(
|
||||
$msg({
|
||||
from: 'lounge@montague.lit/someone',
|
||||
@ -2168,9 +2169,9 @@ describe("Groupchats", function () {
|
||||
}).c('body').t(message).tree());
|
||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 21);
|
||||
// Now check that the message appears inside the chatbox in the DOM
|
||||
const msg_txt = sizzle('.chat-msg:last .chat-msg__text', view.content).pop().textContent;
|
||||
const msg_txt = sizzle('.chat-msg:last .chat-msg__text', content).pop().textContent;
|
||||
expect(msg_txt).toEqual(message);
|
||||
expect(view.content.scrollTop).toBe(0);
|
||||
expect(content.scrollTop).toBe(0);
|
||||
done();
|
||||
}, 500);
|
||||
}));
|
||||
@ -2346,8 +2347,8 @@ describe("Groupchats", function () {
|
||||
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
expect(view.model.session.get('connection_status')).toBe(converse.ROOMSTATUS.ENTERED);
|
||||
expect(view.content.querySelectorAll('div.chat-info').length).toBe(1);
|
||||
expect(sizzle('div.chat-info', view.content)[0].textContent.trim()).toBe(
|
||||
expect(view.querySelectorAll('div.chat-info').length).toBe(1);
|
||||
expect(sizzle('div.chat-info', view)[0].textContent.trim()).toBe(
|
||||
__(_converse.muc.new_nickname_messages["303"], "newnick")
|
||||
);
|
||||
occupants = view.querySelector('.occupant-list');
|
||||
@ -2964,7 +2965,7 @@ describe("Groupchats", function () {
|
||||
bottom_panel.onKeyDown(enter);
|
||||
|
||||
await u.waitUntil(() => sizzle('converse-chat-help .chat-info', view).length);
|
||||
const chat_help_el = view.querySelector('converse-chat-help');
|
||||
let chat_help_el = view.querySelector('converse-chat-help');
|
||||
let info_messages = sizzle('.chat-info', chat_help_el);
|
||||
expect(info_messages.length).toBe(19);
|
||||
expect(info_messages.pop().textContent.trim()).toBe('/voice: Allow muted user to post messages');
|
||||
@ -2991,11 +2992,12 @@ describe("Groupchats", function () {
|
||||
occupant.set('affiliation', 'admin');
|
||||
|
||||
view.querySelector('.close-chat-help').click();
|
||||
await u.waitUntil(() => chat_help_el.hidden);
|
||||
expect(view.model.get('show_help_messages')).toBe(false);
|
||||
await u.waitUntil(() => view.querySelector('converse-chat-help') === null);
|
||||
|
||||
textarea.value = '/help';
|
||||
bottom_panel.onKeyDown(enter);
|
||||
await u.waitUntil(() => !chat_help_el.hidden);
|
||||
chat_help_el = await u.waitUntil(() => view.querySelector('converse-chat-help'));
|
||||
info_messages = sizzle('.chat-info', chat_help_el);
|
||||
expect(info_messages.length).toBe(18);
|
||||
let commands = info_messages.map(m => m.textContent.replace(/:.*$/, ''));
|
||||
@ -3006,18 +3008,18 @@ describe("Groupchats", function () {
|
||||
]);
|
||||
occupant.set('affiliation', 'member');
|
||||
view.querySelector('.close-chat-help').click();
|
||||
await u.waitUntil(() => chat_help_el.hidden);
|
||||
await u.waitUntil(() => view.querySelector('converse-chat-help') === null);
|
||||
|
||||
textarea.value = '/help';
|
||||
bottom_panel.onKeyDown(enter);
|
||||
await u.waitUntil(() => !chat_help_el.hidden);
|
||||
chat_help_el = await u.waitUntil(() => view.querySelector('converse-chat-help'));
|
||||
info_messages = sizzle('.chat-info', chat_help_el);
|
||||
expect(info_messages.length).toBe(9);
|
||||
commands = info_messages.map(m => m.textContent.replace(/:.*$/, ''));
|
||||
expect(commands).toEqual(["/clear", "/help", "/kick", "/me", "/modtools", "/mute", "/nick", "/register", "/voice"]);
|
||||
|
||||
view.querySelector('.close-chat-help').click();
|
||||
await u.waitUntil(() => chat_help_el.hidden);
|
||||
await u.waitUntil(() => view.querySelector('converse-chat-help') === null);
|
||||
expect(view.model.get('show_help_messages')).toBe(false);
|
||||
|
||||
occupant.set('role', 'participant');
|
||||
@ -3026,7 +3028,7 @@ describe("Groupchats", function () {
|
||||
textarea.value = '/help';
|
||||
bottom_panel.onKeyDown(enter);
|
||||
await u.waitUntil(() => view.model.get('show_help_messages'));
|
||||
await u.waitUntil(() => !chat_help_el.hidden);
|
||||
chat_help_el = await u.waitUntil(() => view.querySelector('converse-chat-help'));
|
||||
info_messages = sizzle('.chat-info', chat_help_el);
|
||||
expect(info_messages.length).toBe(5);
|
||||
commands = info_messages.map(m => m.textContent.replace(/:.*$/, ''));
|
||||
@ -3036,11 +3038,11 @@ describe("Groupchats", function () {
|
||||
// Note: we're making a shortcut here, this value should never be set manually
|
||||
view.model.config.set('changesubject', true);
|
||||
view.querySelector('.close-chat-help').click();
|
||||
await u.waitUntil(() => chat_help_el.hidden);
|
||||
await u.waitUntil(() => view.querySelector('converse-chat-help') === null);
|
||||
|
||||
textarea.value = '/help';
|
||||
bottom_panel.onKeyDown(enter);
|
||||
await u.waitUntil(() => !chat_help_el.hidden, 1000);
|
||||
chat_help_el = await u.waitUntil(() => view.querySelector('converse-chat-help'));
|
||||
info_messages = sizzle('.chat-info', chat_help_el);
|
||||
expect(info_messages.length).toBe(7);
|
||||
commands = info_messages.map(m => m.textContent.replace(/:.*$/, ''));
|
||||
|
@ -73,7 +73,7 @@ const RosterContacts = Collection.extend({
|
||||
if (u.isErrorObject(result)) {
|
||||
log.error(result);
|
||||
// Force a full roster refresh
|
||||
_converse.session.set('roster_cached', false)
|
||||
_converse.session.save('roster_cached', false)
|
||||
this.data.save('version', undefined);
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,10 @@ export default class ChatBottomPanel extends ElementView {
|
||||
super.connectedCallback();
|
||||
this.model = _converse.chatboxes.get(this.getAttribute('jid'));
|
||||
this.listenTo(this.model, 'change:composing_spoiler', this.renderMessageForm);
|
||||
|
||||
await this.model.initialized;
|
||||
this.listenTo(this.model.messages, 'change:correcting', this.onMessageCorrecting);
|
||||
this.render();
|
||||
api.listen.on('chatBoxScrolledDown', () => this.hideNewMessagesIndicator());
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -79,6 +79,10 @@ export default class ChatBottomPanel extends ElementView {
|
||||
this.renderToolbar();
|
||||
}
|
||||
|
||||
hideNewMessagesIndicator () {
|
||||
this.querySelector('.new-msgs-indicator')?.classList.add('hidden');
|
||||
}
|
||||
|
||||
onMessageCorrecting (message) {
|
||||
if (message.get('correcting')) {
|
||||
this.insertIntoTextArea(u.prefixMentions(message), true, true);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'plugins/chatview/heading.js';
|
||||
import 'plugins/chatview/bottom_panel.js';
|
||||
import { html, render } from 'lit-html';
|
||||
import BaseChatView from 'shared/chat/baseview.js';
|
||||
import tpl_chat from './templates/chat.js';
|
||||
import { __ } from 'i18n';
|
||||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
import { render } from 'lit-html';
|
||||
|
||||
const u = converse.env.utils;
|
||||
const { dayjs } = converse.env;
|
||||
@ -58,11 +58,25 @@ export default class ChatView extends BaseChatView {
|
||||
this.model.toJSON(), { 'markScrolled': ev => this.markScrolled(ev) })
|
||||
);
|
||||
render(result, this);
|
||||
this.content = this.querySelector('.chat-content');
|
||||
this.help_container = this.querySelector('.chat-content__help');
|
||||
return this;
|
||||
}
|
||||
|
||||
renderHelpMessages () {
|
||||
render(
|
||||
html`
|
||||
<converse-chat-help
|
||||
.model=${this.model}
|
||||
.messages=${this.getHelpMessages()}
|
||||
?hidden=${!this.model.get('show_help_messages')}
|
||||
type="info"
|
||||
chat_type="${this.model.get('type')}"
|
||||
></converse-chat-help>
|
||||
`,
|
||||
this.help_container
|
||||
);
|
||||
}
|
||||
|
||||
getHelpMessages () { // eslint-disable-line class-methods-use-this
|
||||
return [
|
||||
`<strong>/clear</strong>: ${__('Remove messages')}`,
|
||||
|
@ -52,7 +52,6 @@ class HeadlinesView extends BaseChatView {
|
||||
})
|
||||
);
|
||||
render(result, this);
|
||||
this.content = this.querySelector('.chat-content');
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -190,10 +190,11 @@ function onMaximized (view) {
|
||||
*/
|
||||
function onMinimized (view) {
|
||||
// save the scroll position to restore it on maximize
|
||||
const content = view.querySelector('.chat-content__messages');
|
||||
if (view.model.collection && view.model.collection.browserStorage) {
|
||||
view.model.save({ 'scroll': view.content.scrollTop });
|
||||
view.model.save({ 'scroll': content.scrollTop });
|
||||
} else {
|
||||
view.model.set({ 'scroll': view.content.scrollTop });
|
||||
view.model.set({ 'scroll': content.scrollTop });
|
||||
}
|
||||
view.model.setChatState(_converse.INACTIVE);
|
||||
/**
|
||||
|
129
src/plugins/muc-views/chatarea.js
Normal file
129
src/plugins/muc-views/chatarea.js
Normal file
@ -0,0 +1,129 @@
|
||||
import debounce from 'lodash-es/debounce';
|
||||
import tpl_muc_chatarea from './templates/muc-chatarea.js';
|
||||
import { CustomElement } from 'components/element.js';
|
||||
import { __ } from 'i18n';
|
||||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
|
||||
|
||||
const { u } = converse.env;
|
||||
|
||||
|
||||
export default class MUCChatArea extends CustomElement {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
jid: { type: String },
|
||||
show_help_messages: { type: Boolean },
|
||||
type: { type: String },
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback () {
|
||||
super.connectedCallback();
|
||||
this.model = _converse.chatboxes.get(this.jid);
|
||||
this.markScrolled = debounce(this._markScrolled, 100);
|
||||
this.listenTo(this.model, 'change:show_help_messages', () => this.requestUpdate());
|
||||
}
|
||||
|
||||
render () {
|
||||
return tpl_muc_chatarea({
|
||||
'help_messages': this.getHelpMessages(),
|
||||
'jid': this.jid,
|
||||
'model': this.model,
|
||||
'occupants': this.model.occupants,
|
||||
'show_help_messages': this.model.get('show_help_messages'),
|
||||
'show_send_button': _converse.show_send_button,
|
||||
'show_sidebar': this.shouldShowSidebar(),
|
||||
'type': this.type,
|
||||
});
|
||||
}
|
||||
|
||||
shouldShowSidebar () {
|
||||
return (
|
||||
!this.model.get('hidden_occupants') &&
|
||||
this.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED
|
||||
);
|
||||
}
|
||||
|
||||
getHelpMessages () {
|
||||
const setting = api.settings.get('muc_disable_slash_commands');
|
||||
const disabled_commands = Array.isArray(setting) ? setting : [];
|
||||
return [
|
||||
`<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
|
||||
`<strong>/ban</strong>: ${__('Ban user by changing their affiliation to outcast')}`,
|
||||
`<strong>/clear</strong>: ${__('Clear the chat area')}`,
|
||||
`<strong>/close</strong>: ${__('Close this groupchat')}`,
|
||||
`<strong>/deop</strong>: ${__('Change user role to participant')}`,
|
||||
`<strong>/destroy</strong>: ${__('Remove this groupchat')}`,
|
||||
`<strong>/help</strong>: ${__('Show this menu')}`,
|
||||
`<strong>/kick</strong>: ${__('Kick user from groupchat')}`,
|
||||
`<strong>/me</strong>: ${__('Write in 3rd person')}`,
|
||||
`<strong>/member</strong>: ${__('Grant membership to a user')}`,
|
||||
`<strong>/modtools</strong>: ${__('Opens up the moderator tools GUI')}`,
|
||||
`<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`,
|
||||
`<strong>/nick</strong>: ${__('Change your nickname')}`,
|
||||
`<strong>/op</strong>: ${__('Grant moderator role to user')}`,
|
||||
`<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`,
|
||||
`<strong>/register</strong>: ${__('Register your nickname')}`,
|
||||
`<strong>/revoke</strong>: ${__("Revoke the user's current affiliation")}`,
|
||||
`<strong>/subject</strong>: ${__('Set groupchat subject')}`,
|
||||
`<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`,
|
||||
`<strong>/voice</strong>: ${__('Allow muted user to post messages')}`
|
||||
]
|
||||
.filter(line => disabled_commands.every(c => !line.startsWith(c + '<', 9)))
|
||||
.filter(line => this.model.getAllowedCommands().some(c => line.startsWith(c + '<', 9)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the chat content is scrolled up or down.
|
||||
* We want to record when the user has scrolled away from
|
||||
* the bottom, so that we don't automatically scroll away
|
||||
* from what the user is reading when new messages are received.
|
||||
*
|
||||
* Don't call this method directly, instead, call `markScrolled`,
|
||||
* which debounces this method by 100ms.
|
||||
* @private
|
||||
*/
|
||||
_markScrolled (ev) {
|
||||
let scrolled = true;
|
||||
let scrollTop = null;
|
||||
const msgs_container = this.querySelector('.chat-content__messages');
|
||||
const is_at_bottom =
|
||||
msgs_container.scrollTop + msgs_container.clientHeight >= msgs_container.scrollHeight - 62; // sigh...
|
||||
|
||||
if (is_at_bottom) {
|
||||
scrolled = false;
|
||||
this.onScrolledDown();
|
||||
} else if (msgs_container.scrollTop === 0) {
|
||||
/**
|
||||
* Triggered once the chat's message area has been scrolled to the top
|
||||
* @event _converse#chatBoxScrolledUp
|
||||
* @property { _converse.ChatBoxView | _converse.ChatRoomView } view
|
||||
* @example _converse.api.listen.on('chatBoxScrolledUp', obj => { ... });
|
||||
*/
|
||||
api.trigger('chatBoxScrolledUp', this);
|
||||
} else {
|
||||
scrollTop = ev.target.scrollTop;
|
||||
}
|
||||
u.safeSave(this.model, { scrolled, scrollTop });
|
||||
}
|
||||
|
||||
onScrolledDown () {
|
||||
if (!this.model.isHidden()) {
|
||||
this.model.clearUnreadMsgCounter();
|
||||
// Clear location hash if set to one of the messages in our history
|
||||
const hash = window.location.hash;
|
||||
hash && this.model.messages.get(hash.slice(1)) && _converse.router.history.navigate();
|
||||
}
|
||||
/**
|
||||
* Triggered once the chat's message area has been scrolled down to the bottom.
|
||||
* @event _converse#chatBoxScrolledDown
|
||||
* @type {object}
|
||||
* @property { _converse.ChatBox | _converse.ChatRoom } chatbox - The chat model
|
||||
* @example _converse.api.listen.on('chatBoxScrolledDown', obj => { ... });
|
||||
*/
|
||||
api.trigger('chatBoxScrolledDown', { 'chatbox': this.model });
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-muc-chatarea', MUCChatArea);
|
@ -63,7 +63,6 @@ export default class MUCView extends BaseChatView {
|
||||
await this.render();
|
||||
|
||||
// Need to be registered after render has been called.
|
||||
this.listenTo(this.model, 'change:show_help_messages', this.renderHelpMessages);
|
||||
this.listenTo(this.model.messages, 'add', this.onMessageAdded);
|
||||
this.listenTo(this.model.occupants, 'change:show', this.showJoinOrLeaveNotification);
|
||||
this.listenTo(this.model.occupants, 'remove', this.onOccupantRemoved);
|
||||
@ -85,7 +84,8 @@ export default class MUCView extends BaseChatView {
|
||||
this.setAttribute('id', this.model.get('box_id'));
|
||||
render(
|
||||
tpl_muc({
|
||||
sidebar_hidden,
|
||||
'chatview': this,
|
||||
'conn_status': this.model.session.get('connection_status'),
|
||||
'model': this.model,
|
||||
'occupants': this.model.occupants,
|
||||
'show_sidebar':
|
||||
@ -93,13 +93,13 @@ export default class MUCView extends BaseChatView {
|
||||
this.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED,
|
||||
'markScrolled': ev => this.markScrolled(ev),
|
||||
'muc_show_logs_before_join': api.settings.get('muc_show_logs_before_join'),
|
||||
'show_send_button': _converse.show_send_button
|
||||
'show_send_button': _converse.show_send_button,
|
||||
sidebar_hidden,
|
||||
}),
|
||||
this
|
||||
);
|
||||
|
||||
this.notifications = this.querySelector('.chat-content__notifications');
|
||||
this.content = this.querySelector('.chat-content');
|
||||
this.help_container = this.querySelector('.chat-content__help');
|
||||
|
||||
if (
|
||||
@ -114,35 +114,6 @@ export default class MUCView extends BaseChatView {
|
||||
!this.model.get('hidden') && this.show();
|
||||
}
|
||||
|
||||
getHelpMessages () {
|
||||
const setting = api.settings.get('muc_disable_slash_commands');
|
||||
const disabled_commands = Array.isArray(setting) ? setting : [];
|
||||
return [
|
||||
`<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
|
||||
`<strong>/ban</strong>: ${__('Ban user by changing their affiliation to outcast')}`,
|
||||
`<strong>/clear</strong>: ${__('Clear the chat area')}`,
|
||||
`<strong>/close</strong>: ${__('Close this groupchat')}`,
|
||||
`<strong>/deop</strong>: ${__('Change user role to participant')}`,
|
||||
`<strong>/destroy</strong>: ${__('Remove this groupchat')}`,
|
||||
`<strong>/help</strong>: ${__('Show this menu')}`,
|
||||
`<strong>/kick</strong>: ${__('Kick user from groupchat')}`,
|
||||
`<strong>/me</strong>: ${__('Write in 3rd person')}`,
|
||||
`<strong>/member</strong>: ${__('Grant membership to a user')}`,
|
||||
`<strong>/modtools</strong>: ${__('Opens up the moderator tools GUI')}`,
|
||||
`<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`,
|
||||
`<strong>/nick</strong>: ${__('Change your nickname')}`,
|
||||
`<strong>/op</strong>: ${__('Grant moderator role to user')}`,
|
||||
`<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`,
|
||||
`<strong>/register</strong>: ${__('Register your nickname')}`,
|
||||
`<strong>/revoke</strong>: ${__("Revoke the user's current affiliation")}`,
|
||||
`<strong>/subject</strong>: ${__('Set groupchat subject')}`,
|
||||
`<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`,
|
||||
`<strong>/voice</strong>: ${__('Allow muted user to post messages')}`
|
||||
]
|
||||
.filter(line => disabled_commands.every(c => !line.startsWith(c + '<', 9)))
|
||||
.filter(line => this.model.getAllowedCommands().some(c => line.startsWith(c + '<', 9)));
|
||||
}
|
||||
|
||||
onStartResizeOccupants (ev) {
|
||||
this.resizing = true;
|
||||
this.addEventListener('mousemove', this.onMouseMove);
|
||||
@ -361,7 +332,7 @@ export default class MUCView extends BaseChatView {
|
||||
renderNicknameForm () {
|
||||
if (api.settings.get('muc_show_logs_before_join')) {
|
||||
this.hideSpinner();
|
||||
u.showElement(this.querySelector('.chat-area'));
|
||||
u.showElement(this.querySelector('converse-muc-chatarea'));
|
||||
} else {
|
||||
const form = this.querySelector('.muc-nickname-form');
|
||||
const tpl_result = tpl_muc_nickname_form(this.model.toJSON());
|
||||
@ -443,8 +414,7 @@ export default class MUCView extends BaseChatView {
|
||||
}
|
||||
|
||||
showDestroyedMessage () {
|
||||
u.hideElement(this.querySelector('.chat-area'));
|
||||
u.hideElement(this.querySelector('.occupants'));
|
||||
u.hideElement(this.querySelector('converse-muc-chatarea'));
|
||||
sizzle('.spinner', this).forEach(u.removeElement);
|
||||
|
||||
const reason = this.model.get('destroyed_reason');
|
||||
@ -472,8 +442,7 @@ export default class MUCView extends BaseChatView {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
u.hideElement(this.querySelector('.chat-area'));
|
||||
u.hideElement(this.querySelector('.occupants'));
|
||||
u.hideElement(this.querySelector('converse-muc-chatarea'));
|
||||
sizzle('.spinner', this).forEach(u.removeElement);
|
||||
|
||||
const messages = [message];
|
||||
@ -542,7 +511,7 @@ export default class MUCView extends BaseChatView {
|
||||
} else if (conn_status === converse.ROOMSTATUS.ENTERED) {
|
||||
this.hideSpinner();
|
||||
this.hideChatRoomContents();
|
||||
u.showElement(this.querySelector('.chat-area'));
|
||||
u.showElement(this.querySelector('converse-muc-chatarea'));
|
||||
this.querySelector('.occupants')?.setVisibility();
|
||||
this.scrollDown();
|
||||
this.maybeFocus();
|
||||
|
27
src/plugins/muc-views/templates/muc-chatarea.js
Normal file
27
src/plugins/muc-views/templates/muc-chatarea.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { html } from "lit-html";
|
||||
import { _converse } from '@converse/headless/core';
|
||||
|
||||
export default (o) => html`
|
||||
<div class="chat-area">
|
||||
<div class="chat-content ${ o.show_send_button ? 'chat-content-sendbutton' : '' }" aria-live="polite">
|
||||
<converse-chat-content
|
||||
class="chat-content__messages"
|
||||
jid="${o.jid}"
|
||||
@scroll=${o.markScrolled}></converse-chat-content>
|
||||
|
||||
${o.show_help_messages ? html`<div class="chat-content__help">
|
||||
<converse-chat-help
|
||||
.model=${o.model}
|
||||
.messages=${o.help_messages}
|
||||
?hidden=${!o.show_help_messages}
|
||||
type="info"
|
||||
chat_type="${_converse.CHATROOMS_TYPE}"
|
||||
></converse-chat-help></div>` : '' }
|
||||
</div>
|
||||
<converse-muc-bottom-panel jid="${o.jid}" class="bottom-panel"></converse-muc-bottom-panel>
|
||||
</div>
|
||||
<div class="disconnect-container hidden"></div>
|
||||
<converse-muc-sidebar class="occupants col-md-3 col-4 ${o.show_sidebar ? '' : 'hidden' }"
|
||||
.occupants=${o.occupants}
|
||||
.chatroom=${o.model}></converse-muc-sidebar>
|
||||
`;
|
@ -1,3 +1,4 @@
|
||||
import '../chatarea.js';
|
||||
import '../bottom_panel.js';
|
||||
import '../heading.js';
|
||||
import '../sidebar.js';
|
||||
@ -8,22 +9,7 @@ export default (o) => html`
|
||||
<converse-dragresize></converse-dragresize>
|
||||
<converse-muc-heading jid="${o.model.get('jid')}" class="chat-head chat-head-chatroom row no-gutters"></converse-muc-heading>
|
||||
<div class="chat-body chatroom-body row no-gutters">
|
||||
<div class="chat-area col">
|
||||
<div class="chat-content ${ o.show_send_button ? 'chat-content-sendbutton' : '' }" aria-live="polite">
|
||||
<converse-chat-content
|
||||
class="chat-content__messages"
|
||||
jid="${o.model.get('jid')}"
|
||||
@scroll=${o.markScrolled}></converse-chat-content>
|
||||
|
||||
<div class="chat-content__help"></div>
|
||||
</div>
|
||||
<converse-muc-bottom-panel jid="${o.model.get('jid')}" class="bottom-panel"></converse-muc-bottom-panel>
|
||||
</div>
|
||||
<div class="disconnect-container hidden"></div>
|
||||
<converse-muc-sidebar class="occupants col-md-3 col-4 ${o.sidebar_hidden ? 'hidden' : ''}"
|
||||
.occupants=${o.occupants}
|
||||
.chatroom=${o.model}></converse-muc-sidebar>
|
||||
<div class="nickname-form-container"></div>
|
||||
<converse-muc-chatarea jid="${o.model.get('jid')}"></converse-muc-chatarea>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -3,7 +3,6 @@ import log from '@converse/headless/log';
|
||||
import tpl_spinner from 'templates/spinner.js';
|
||||
import { ElementView } from '@converse/skeletor/src/element.js';
|
||||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
import { html, render } from 'lit-html';
|
||||
|
||||
const u = converse.env.utils;
|
||||
|
||||
@ -14,21 +13,6 @@ export default class BaseChatView extends ElementView {
|
||||
this.debouncedScrollDown = debounce(this.scrollDown, 100);
|
||||
}
|
||||
|
||||
renderHelpMessages () {
|
||||
render(
|
||||
html`
|
||||
<converse-chat-help
|
||||
.model=${this.model}
|
||||
.messages=${this.getHelpMessages()}
|
||||
?hidden=${!this.model.get('show_help_messages')}
|
||||
type="info"
|
||||
chat_type="${this.model.get('type')}"
|
||||
></converse-chat-help>
|
||||
`,
|
||||
this.help_container
|
||||
);
|
||||
}
|
||||
|
||||
hideNewMessagesIndicator () {
|
||||
const new_msgs_indicator = this.querySelector('.new-msgs-indicator');
|
||||
if (new_msgs_indicator !== null) {
|
||||
@ -103,19 +87,20 @@ export default class BaseChatView extends ElementView {
|
||||
}
|
||||
|
||||
addSpinner (append = false) {
|
||||
const content = this.querySelector('.chat-content');
|
||||
if (this.querySelector('.spinner') === null) {
|
||||
const el = u.getElementFromTemplateResult(tpl_spinner());
|
||||
if (append) {
|
||||
this.content.insertAdjacentElement('beforeend', el);
|
||||
content.insertAdjacentElement('beforeend', el);
|
||||
this.scrollDown();
|
||||
} else {
|
||||
this.content.insertAdjacentElement('afterbegin', el);
|
||||
content.insertAdjacentElement('afterbegin', el);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearSpinner () {
|
||||
this.content.querySelectorAll('.spinner').forEach(u.removeElement);
|
||||
this.querySelectorAll('.chat-content .spinner').forEach(u.removeElement);
|
||||
}
|
||||
|
||||
onStatusMessageChanged (item) {
|
||||
|
Loading…
Reference in New Issue
Block a user