Reduce join/leave clutter by removing subsequent ones
Previously we checked only if the last message was a join message from the same person. Now instead we check the last n messages that are join or leave notifications.
This commit is contained in:
parent
cf75d37587
commit
71cc98d6f6
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## 4.0.3 (Unreleased)
|
## 4.0.3 (Unreleased)
|
||||||
|
|
||||||
|
- Reduce join/leave clutter by removing subsequent ones (without text messages in between)
|
||||||
- Bugfix. Handler not triggered when submitting MUC password form 2nd time
|
- Bugfix. Handler not triggered when submitting MUC password form 2nd time
|
||||||
- Bugfix. MUC features weren't being refreshed when saving the config form
|
- Bugfix. MUC features weren't being refreshed when saving the config form
|
||||||
- #1063 URLs in the topic / subject are not clickable
|
- #1063 URLs in the topic / subject are not clickable
|
||||||
|
41
dist/converse.js
vendored
41
dist/converse.js
vendored
@ -69771,6 +69771,22 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getImmediateJoinNotification(el, nick) {
|
||||||
|
while (!_.isNil(el)) {
|
||||||
|
const data = _.get(el, 'dataset', {});
|
||||||
|
|
||||||
|
if (!_.includes(_.get(el, 'classList', []), 'chat-info')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moment(el.getAttribute('data-isodate')).isSame(new Date(), "day") && (data.join === `"${nick}"` || data.leavejoin === `"${nick}"`)) {
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
el = el.previousElementSibling;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
showLeaveNotification(occupant) {
|
showLeaveNotification(occupant) {
|
||||||
if (_.includes(occupant.get('states'), '303') || _.includes(occupant.get('states'), '307')) {
|
if (_.includes(occupant.get('states'), '303') || _.includes(occupant.get('states'), '307')) {
|
||||||
return;
|
return;
|
||||||
@ -69778,10 +69794,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
|
|
||||||
const nick = occupant.get('nick'),
|
const nick = occupant.get('nick'),
|
||||||
stat = occupant.get('status'),
|
stat = occupant.get('status'),
|
||||||
last_el = this.content.lastElementChild,
|
last_join_el = this.getImmediateJoinNotification(this.content.lastElementChild, nick),
|
||||||
data = _.get(last_el, 'dataset', {});
|
data = _.get(last_join_el, 'dataset', {});
|
||||||
|
|
||||||
if (last_el && _.includes(_.get(last_el, 'classList', []), 'chat-info') && moment(last_el.getAttribute('data-isodate')).isSame(new Date(), "day") && (data.join === `"${nick}"` || data.leavejoin === `"${nick}"`)) {
|
if (last_join_el) {
|
||||||
let message;
|
let message;
|
||||||
|
|
||||||
if (data.join === `"${nick}"`) {
|
if (data.join === `"${nick}"`) {
|
||||||
@ -69791,13 +69807,15 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
message = __('%1$s has entered and left the groupchat. "%2$s"', nick, stat);
|
message = __('%1$s has entered and left the groupchat. "%2$s"', nick, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_el.outerHTML = tpl_info({
|
let el = this.content.lastElementChild;
|
||||||
|
el.insertAdjacentElement('afterend', last_join_el);
|
||||||
|
last_join_el.outerHTML = tpl_info({
|
||||||
'data': `data-joinleave="${nick}"`,
|
'data': `data-joinleave="${nick}"`,
|
||||||
'isodate': moment().format(),
|
'isodate': moment().format(),
|
||||||
'extra_classes': 'chat-event',
|
'extra_classes': 'chat-event',
|
||||||
'message': message
|
'message': message
|
||||||
});
|
});
|
||||||
const el = this.content.lastElementChild;
|
el = this.content.lastElementChild;
|
||||||
setTimeout(() => u.addClass('fade-out', el), 5000);
|
setTimeout(() => u.addClass('fade-out', el), 5000);
|
||||||
setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5250);
|
setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5250);
|
||||||
} else if (data.leavejoin === `"${nick}"`) {
|
} else if (data.leavejoin === `"${nick}"`) {
|
||||||
@ -69807,7 +69825,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
message = __('%1$s has left the groupchat. "%2$s"', nick, stat);
|
message = __('%1$s has left the groupchat. "%2$s"', nick, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_el.outerHTML = tpl_info({
|
last_join_el.outerHTML = tpl_info({
|
||||||
'data': `data-leave="${nick}"`,
|
'data': `data-leave="${nick}"`,
|
||||||
'isodate': moment().format(),
|
'isodate': moment().format(),
|
||||||
'extra_classes': 'chat-event',
|
'extra_classes': 'chat-event',
|
||||||
@ -69829,14 +69847,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
'extra_classes': 'chat-event',
|
'extra_classes': 'chat-event',
|
||||||
'data': `data-leave="${nick}"`
|
'data': `data-leave="${nick}"`
|
||||||
};
|
};
|
||||||
|
const el = u.stringToElement(tpl_info(data));
|
||||||
if (last_el && _.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) {
|
this.content.insertAdjacentElement('beforeend', el);
|
||||||
last_el.outerHTML = tpl_info(data);
|
this.insertDayIndicator(el);
|
||||||
} else {
|
|
||||||
const el = u.stringToElement(tpl_info(data));
|
|
||||||
this.content.insertAdjacentElement('beforeend', el);
|
|
||||||
this.insertDayIndicator(el);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
|
@ -422,7 +422,8 @@
|
|||||||
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1')
|
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
||||||
const $chat_content = $(view.el).find('.chat-content');
|
const chat_content = view.el.querySelector('.chat-content');
|
||||||
|
const $chat_content = $(chat_content);
|
||||||
/* We don't show join/leave messages for existing occupants. We
|
/* We don't show join/leave messages for existing occupants. We
|
||||||
* know about them because we receive their presences before we
|
* know about them because we receive their presences before we
|
||||||
* receive our own.
|
* receive our own.
|
||||||
@ -474,6 +475,15 @@
|
|||||||
expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(2);
|
expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(2);
|
||||||
expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
|
expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
|
||||||
|
|
||||||
|
const msg = $msg({
|
||||||
|
'from': 'coven@chat.shakespeare.lit/some1',
|
||||||
|
'id': (new Date()).getTime(),
|
||||||
|
'to': 'dummy@localhost',
|
||||||
|
'type': 'groupchat'
|
||||||
|
}).c('body').t('hello world').tree();
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(msg));
|
||||||
|
|
||||||
|
|
||||||
// Add another entrant, otherwise the above message will be
|
// Add another entrant, otherwise the above message will be
|
||||||
// collapsed if "newguy" leaves immediately again
|
// collapsed if "newguy" leaves immediately again
|
||||||
presence = $pres({
|
presence = $pres({
|
||||||
@ -563,9 +573,9 @@
|
|||||||
});
|
});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
expect($chat_content.find('div.chat-info').length).toBe(4);
|
expect($chat_content.find('div.chat-info').length).toBe(4);
|
||||||
$msg_el = $chat_content.find('div.chat-info:last');
|
const msg_el = sizzle('div.chat-info', chat_content).pop();
|
||||||
expect($msg_el.html()).toBe('newguy has left the groupchat');
|
expect(msg_el.textContent).toBe('newguy has left the groupchat');
|
||||||
expect($msg_el.data('leave')).toBe('"newguy"');
|
expect(msg_el.getAttribute('data-leave')).toBe('"newguy"');
|
||||||
|
|
||||||
presence = $pres({
|
presence = $pres({
|
||||||
to: 'dummy@localhost/_converse.js-29092160',
|
to: 'dummy@localhost/_converse.js-29092160',
|
||||||
@ -648,13 +658,31 @@
|
|||||||
'role': 'none'
|
'role': 'none'
|
||||||
});
|
});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
expect($chat_content.find('div.chat-info').length).toBe(6);
|
expect(chat_content.querySelectorAll('div.chat-info').length).toBe(6);
|
||||||
expect($chat_content.find('div.chat-info:last').html()).toBe(
|
expect($chat_content.find('div.chat-info:last').html()).toBe(
|
||||||
'insider has entered and left the groupchat. '+
|
'insider has entered and left the groupchat. '+
|
||||||
'"Disconnected: Replaced by new connection"');
|
'"Disconnected: Replaced by new connection"');
|
||||||
|
|
||||||
expect(view.model.occupants.length).toBe(5);
|
expect(view.model.occupants.length).toBe(5);
|
||||||
expect(view.model.occupants.findWhere({'jid': 'insider@localhost'}).get('show')).toBe('offline');
|
expect(view.model.occupants.findWhere({'jid': 'insider@localhost'}).get('show')).toBe('offline');
|
||||||
|
|
||||||
|
// New girl leaves
|
||||||
|
presence = $pres({
|
||||||
|
'to': 'dummy@localhost/_converse.js-29092160',
|
||||||
|
'type': 'unavailable',
|
||||||
|
'from': 'coven@chat.shakespeare.lit/newgirl'
|
||||||
|
})
|
||||||
|
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||||
|
.c('item', {
|
||||||
|
'affiliation': 'none',
|
||||||
|
'jid': 'newgirl@localhost/_converse.js-213098781',
|
||||||
|
'role': 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
|
expect(chat_content.querySelectorAll('div.chat-info').length).toBe(6);
|
||||||
|
expect(sizzle('div.chat-info:last', chat_content).pop().textContent).toBe("newgirl has entered and left the groupchat");
|
||||||
|
expect(view.model.occupants.length).toBe(4);
|
||||||
done();
|
done();
|
||||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
|
||||||
}));
|
}));
|
||||||
|
@ -1546,20 +1546,30 @@
|
|||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getImmediateJoinNotification (el, nick) {
|
||||||
|
while (!_.isNil(el)) {
|
||||||
|
const data = _.get(el, 'dataset', {});
|
||||||
|
if (!_.includes(_.get(el, 'classList', []), 'chat-info')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (moment(el.getAttribute('data-isodate')).isSame(new Date(), "day") &&
|
||||||
|
(data.join === `"${nick}"` || data.leavejoin === `"${nick}"`)) {
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
el = el.previousElementSibling;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
showLeaveNotification (occupant) {
|
showLeaveNotification (occupant) {
|
||||||
if (_.includes(occupant.get('states'), '303') || _.includes(occupant.get('states'), '307')) {
|
if (_.includes(occupant.get('states'), '303') || _.includes(occupant.get('states'), '307')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const nick = occupant.get('nick'),
|
const nick = occupant.get('nick'),
|
||||||
stat = occupant.get('status'),
|
stat = occupant.get('status'),
|
||||||
last_el = this.content.lastElementChild,
|
last_join_el = this.getImmediateJoinNotification(this.content.lastElementChild, nick),
|
||||||
data = _.get(last_el, 'dataset', {});
|
data = _.get(last_join_el, 'dataset', {});
|
||||||
|
|
||||||
if (last_el &&
|
|
||||||
_.includes(_.get(last_el, 'classList', []), 'chat-info') &&
|
|
||||||
moment(last_el.getAttribute('data-isodate')).isSame(new Date(), "day") &&
|
|
||||||
(data.join === `"${nick}"` || data.leavejoin === `"${nick}"`)) {
|
|
||||||
|
|
||||||
|
if (last_join_el) {
|
||||||
let message;
|
let message;
|
||||||
if (data.join === `"${nick}"`) {
|
if (data.join === `"${nick}"`) {
|
||||||
if (_.isNil(stat)) {
|
if (_.isNil(stat)) {
|
||||||
@ -1567,24 +1577,25 @@
|
|||||||
} else {
|
} else {
|
||||||
message = __('%1$s has entered and left the groupchat. "%2$s"', nick, stat);
|
message = __('%1$s has entered and left the groupchat. "%2$s"', nick, stat);
|
||||||
}
|
}
|
||||||
last_el.outerHTML =
|
let el = this.content.lastElementChild;
|
||||||
|
el.insertAdjacentElement('afterend', last_join_el);
|
||||||
|
last_join_el.outerHTML =
|
||||||
tpl_info({
|
tpl_info({
|
||||||
'data': `data-joinleave="${nick}"`,
|
'data': `data-joinleave="${nick}"`,
|
||||||
'isodate': moment().format(),
|
'isodate': moment().format(),
|
||||||
'extra_classes': 'chat-event',
|
'extra_classes': 'chat-event',
|
||||||
'message': message
|
'message': message
|
||||||
});
|
});
|
||||||
const el = this.content.lastElementChild;
|
el = this.content.lastElementChild;
|
||||||
setTimeout(() => u.addClass('fade-out', el), 5000);
|
setTimeout(() => u.addClass('fade-out', el), 5000);
|
||||||
setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5250);
|
setTimeout(() => el.parentElement && el.parentElement.removeChild(el), 5250);
|
||||||
|
|
||||||
} else if (data.leavejoin === `"${nick}"`) {
|
} else if (data.leavejoin === `"${nick}"`) {
|
||||||
if (_.isNil(stat)) {
|
if (_.isNil(stat)) {
|
||||||
message = __('%1$s has left the groupchat', nick);
|
message = __('%1$s has left the groupchat', nick);
|
||||||
} else {
|
} else {
|
||||||
message = __('%1$s has left the groupchat. "%2$s"', nick, stat);
|
message = __('%1$s has left the groupchat. "%2$s"', nick, stat);
|
||||||
}
|
}
|
||||||
last_el.outerHTML =
|
last_join_el.outerHTML =
|
||||||
tpl_info({
|
tpl_info({
|
||||||
'data': `data-leave="${nick}"`,
|
'data': `data-leave="${nick}"`,
|
||||||
'isodate': moment().format(),
|
'isodate': moment().format(),
|
||||||
@ -1605,16 +1616,9 @@
|
|||||||
'extra_classes': 'chat-event',
|
'extra_classes': 'chat-event',
|
||||||
'data': `data-leave="${nick}"`
|
'data': `data-leave="${nick}"`
|
||||||
}
|
}
|
||||||
if (last_el &&
|
const el = u.stringToElement(tpl_info(data));
|
||||||
_.includes(_.get(last_el, 'classList', []), 'chat-info') &&
|
this.content.insertAdjacentElement('beforeend', el);
|
||||||
_.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) {
|
this.insertDayIndicator(el);
|
||||||
|
|
||||||
last_el.outerHTML = tpl_info(data);
|
|
||||||
} else {
|
|
||||||
const el = u.stringToElement(tpl_info(data));
|
|
||||||
this.content.insertAdjacentElement('beforeend', el);
|
|
||||||
this.insertDayIndicator(el);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user