MUC: Don't show topic change notification for old changes.
Also, show topic by creating a message object, instead of directly inserting HTML into the DOM. This is a necessary precursor to being able to render chat messages via lit-html/lit-element.
This commit is contained in:
parent
3e27a5ec81
commit
5fd316816d
65
spec/muc.js
65
spec/muc.js
@ -501,7 +501,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe("the topic", function () {
|
||||
describe("topic", function () {
|
||||
|
||||
it("is shown the header",
|
||||
mock.initConverse(
|
||||
@ -511,7 +511,7 @@
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
|
||||
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
|
||||
let stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>${text}</subject>
|
||||
<delay xmlns="urn:xmpp:delay" stamp="2014-02-04T09:35:39Z" from="jdev@conference.jabber.org"/>
|
||||
<x xmlns="jabber:x:delay" stamp="20140204T09:35:39" from="jdev@conference.jabber.org"/>
|
||||
@ -520,12 +520,11 @@
|
||||
const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
|
||||
await new Promise(resolve => view.model.once('change:subject', resolve));
|
||||
|
||||
expect(sizzle('.chat-event:last', view.el).pop().textContent.trim()).toBe('Topic set by ralphm');
|
||||
const head_desc = await u.waitUntil(() => view.el.querySelector('.chat-head__desc'));
|
||||
expect(head_desc?.textContent.trim()).toBe(text);
|
||||
|
||||
stanza = u.toStanza(
|
||||
`<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
`<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>This is a message subject</subject>
|
||||
<body>This is a message</body>
|
||||
</message>`);
|
||||
@ -536,16 +535,6 @@
|
||||
expect(sizzle('.chat-msg__text').length).toBe(1);
|
||||
expect(sizzle('.chat-msg__text').pop().textContent.trim()).toBe('This is a message');
|
||||
expect(view.el.querySelector('.chat-head__desc').textContent.trim()).toBe(text);
|
||||
|
||||
// Removes current topic
|
||||
stanza = u.toStanza(
|
||||
`<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
await new Promise(resolve => view.model.once('change:subject', resolve));
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-head__desc') === null);
|
||||
expect(view.el.querySelector('.chat-info:last-child').textContent.trim()).toBe("Topic cleared by ralphm");
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -557,7 +546,7 @@
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
|
||||
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
|
||||
let stanza = u.toStanza(`
|
||||
<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>${text}</subject>
|
||||
<delay xmlns="urn:xmpp:delay" stamp="2014-02-04T09:35:39Z" from="jdev@conference.jabber.org"/>
|
||||
<x xmlns="jabber:x:delay" stamp="20140204T09:35:39" from="jdev@conference.jabber.org"/>
|
||||
@ -566,12 +555,11 @@
|
||||
const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
|
||||
await new Promise(resolve => view.model.once('change:subject', resolve));
|
||||
|
||||
expect(sizzle('.chat-event:last', view.el).pop().textContent.trim()).toBe('Topic set by ralphm');
|
||||
const head_desc = await u.waitUntil(() => view.el.querySelector('.chat-head__desc'));
|
||||
expect(head_desc?.textContent.trim()).toBe(text);
|
||||
|
||||
stanza = u.toStanza(
|
||||
`<message xmlns="jabber:client" to="jc@opkode.com/_converse.js-60429116" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
`<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>This is a message subject</subject>
|
||||
<body>This is a message</body>
|
||||
</message>`);
|
||||
@ -592,6 +580,49 @@
|
||||
expect(view.el.querySelector('.hide-topic').textContent).toBe('Show topic');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("causes an info message to be shown when received in real-time",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse.ChatRoom.prototype, 'handleSubjectChange').and.callThrough();
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'romeo');
|
||||
const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
|
||||
|
||||
_converse.connection._dataRecv(test_utils.createRequest(u.toStanza(`
|
||||
<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>This is an older topic</subject>
|
||||
<delay xmlns="urn:xmpp:delay" stamp="2014-02-04T09:35:39Z" from="jdev@conference.jabber.org"/>
|
||||
<x xmlns="jabber:x:delay" stamp="20140204T09:35:39" from="jdev@conference.jabber.org"/>
|
||||
</message>`)));
|
||||
await u.waitUntil(() => view.model.handleSubjectChange.calls.count());
|
||||
expect(sizzle('.chat-info__message', view.el).length).toBe(0);
|
||||
|
||||
const desc = await u.waitUntil(() => view.el.querySelector('.chat-head__desc'));
|
||||
expect(desc.textContent.trim()).toBe('This is an older topic');
|
||||
|
||||
_converse.connection._dataRecv(test_utils.createRequest(u.toStanza(`
|
||||
<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject>This is a new topic</subject>
|
||||
</message>`)));
|
||||
await u.waitUntil(() => view.model.handleSubjectChange.calls.count() === 2);
|
||||
|
||||
const el = sizzle('.chat-info__message', view.el).pop();
|
||||
expect(el.textContent.trim()).toBe('Topic set by ralphm');
|
||||
await u.waitUntil(() => desc.textContent.trim() === 'This is a new topic');
|
||||
|
||||
// Removes current topic
|
||||
const stanza = u.toStanza(
|
||||
`<message xmlns="jabber:client" to="${_converse.jid}" type="groupchat" from="jdev@conference.jabber.org/ralphm">
|
||||
<subject/>
|
||||
</message>`);
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
await u.waitUntil(() => view.model.handleSubjectChange.calls.count() === 3);
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-head__desc') === null);
|
||||
expect(view.el.querySelector('.chat-info:last-child').textContent.trim()).toBe("Topic cleared by ralphm");
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
@ -235,8 +235,8 @@
|
||||
'text': subject,
|
||||
'author': 'ralphm'
|
||||
}});
|
||||
expect(sizzle('.chat-event:last').pop().textContent.trim()).toBe('Topic set by ralphm');
|
||||
await u.waitUntil(() => view.el.querySelector('.chat-head__desc')?.textContent.trim() === subject);
|
||||
const text = await u.waitUntil(() => view.el.querySelector('.chat-head__desc')?.textContent.trim());
|
||||
expect(text).toBe(subject);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
@ -708,7 +708,6 @@ converse.plugins.add('converse-muc-views', {
|
||||
|
||||
this.listenTo(this.model, 'change', debounce(() => this.renderHeading(), 250));
|
||||
this.listenTo(this.model, 'change:hidden_occupants', this.updateOccupantsToggle);
|
||||
this.listenTo(this.model, 'change:subject', this.setChatRoomSubject);
|
||||
this.listenTo(this.model, 'configurationNeeded', this.getAndRenderConfigurationForm);
|
||||
this.listenTo(this.model, 'destroy', this.hide);
|
||||
this.listenTo(this.model, 'show', this.show);
|
||||
@ -2004,26 +2003,6 @@ converse.plugins.add('converse-muc-views', {
|
||||
this.renderAfterTransition();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
setChatRoomSubject () {
|
||||
const subject = this.model.get('subject');
|
||||
if (!subject.text && !subject.author) {
|
||||
return; // Probably a new MUC
|
||||
}
|
||||
const author = subject.author;
|
||||
// For translators: the %1$s part will get
|
||||
// replaced by the user's name.
|
||||
// Example: Topic set by JC Brand
|
||||
const message = subject.text ? __('Topic set by %1$s', author) : __('Topic cleared by %1$s', author);
|
||||
this.msgs_container.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
tpl_info({
|
||||
'isodate': (new Date()).toISOString(),
|
||||
'extra_classes': 'chat-event',
|
||||
'message': message
|
||||
}));
|
||||
this.scrollDown();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1682,22 +1682,34 @@ converse.plugins.add('converse-muc', {
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a subject change and return `true` if so.
|
||||
* Handle a possible subject change and return `true` if so.
|
||||
* @private
|
||||
* @method _converse.ChatRoom#subjectChangeHandled
|
||||
* @param { object } attrs - The message attributes
|
||||
* @method _converse.ChatRoom#handleSubjectChange
|
||||
* @param { object } attrs - Attributes representing a received
|
||||
* message, as returned by {@link stanza_utils.getMessageAttributesFromStanza}
|
||||
*/
|
||||
subjectChangeHandled (attrs) {
|
||||
handleSubjectChange (attrs) {
|
||||
if (isString(attrs.subject) && !attrs.thread && !attrs.message) {
|
||||
// https://xmpp.org/extensions/xep-0045.html#subject-mod
|
||||
// -----------------------------------------------------
|
||||
// The subject is changed by sending a message of type "groupchat" to the <room@service>,
|
||||
// where the <message/> MUST contain a <subject/> element that specifies the new subject but
|
||||
// MUST NOT contain a <body/> element (or a <thread/> element).
|
||||
const subject = attrs.subject;
|
||||
const author = attrs.nick;
|
||||
u.safeSave(this, {
|
||||
'subject': {'author': attrs.nick, 'text': attrs.subject || ''},
|
||||
'subject_hidden': attrs.subject ? false : this.get('subject_hidden')
|
||||
'subject': {author, 'text': attrs.subject || ''},
|
||||
'subject_hidden': subject ? false : this.get('subject_hidden')
|
||||
});
|
||||
if (!attrs.is_delayed) {
|
||||
const message = subject ? __('Topic set by %1$s', author) : __('Topic cleared by %1$s', author);
|
||||
const data = {
|
||||
message,
|
||||
'nick': attrs.nick,
|
||||
'type': 'info'
|
||||
};
|
||||
this.createMessage(data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1998,7 +2010,7 @@ converse.plugins.add('converse-muc', {
|
||||
|
||||
if (await this.handleRetraction(attrs) ||
|
||||
await this.handleModeration(attrs) ||
|
||||
this.subjectChangeHandled(attrs) ||
|
||||
this.handleSubjectChange(attrs) ||
|
||||
this.ignorableCSN(attrs)) {
|
||||
return api.trigger('message', {'stanza': original_stanza});
|
||||
}
|
||||
@ -2070,10 +2082,10 @@ converse.plugins.add('converse-muc', {
|
||||
|
||||
|
||||
/**
|
||||
* Create info messages based on a received presence stanza
|
||||
* Create info messages based on a received presence or message stanza
|
||||
* @private
|
||||
* @method _converse.ChatRoom#createInfoMessages
|
||||
* @param { XMLElement } stanza: The presence stanza received
|
||||
* @param { XMLElement } stanza
|
||||
*/
|
||||
createInfoMessages (stanza) {
|
||||
const is_self = stanza.querySelector("status[code='110']") !== null;
|
||||
|
Loading…
Reference in New Issue
Block a user