Refactored message attributes and rendering.

- set `username` on the message object,
  instead of always using `fullname` with fallback to `jid`.
- Distinguish better between `groupchat` messages and normal
  messages in `getMessageAttributesFromStanza`
This commit is contained in:
JC Brand 2018-05-01 11:46:30 +02:00
parent 54cafb1243
commit f9aa75b69e
6 changed files with 57 additions and 73 deletions

View File

@ -864,7 +864,7 @@
message = '/me is as well'; message = '/me is as well';
msg = $msg({ msg = $msg({
from: 'lounge@localhost/dummy', from: 'lounge@localhost/Max Mustermann',
id: (new Date()).getTime(), id: (new Date()).getTime(),
to: 'dummy@localhost', to: 'dummy@localhost',
type: 'groupchat' type: 'groupchat'

View File

@ -275,7 +275,8 @@
is_spoiler = this.get('composing_spoiler'); is_spoiler = this.get('composing_spoiler');
return { return {
'fullname': _.isEmpty(fullname) ? _converse.bare_jid : fullname, 'fullname': fullname,
'username': _.isEmpty(fullname) ? _converse.bare_jid : fullname,
'sender': 'me', 'sender': 'me',
'time': moment().format(), 'time': moment().format(),
'message': text ? u.httpToGeoUri(emojione.shortnameToUnicode(text), _converse) : undefined, 'message': text ? u.httpToGeoUri(emojione.shortnameToUnicode(text), _converse) : undefined,
@ -362,50 +363,47 @@
* that contains the message stanza, if it was * that contains the message stanza, if it was
* contained, otherwise it's the message stanza itself. * contained, otherwise it's the message stanza itself.
*/ */
const { _converse } = this.__super__,
{ __ } = _converse;
delay = delay || message.querySelector('delay'); delay = delay || message.querySelector('delay');
const type = message.getAttribute('type'),
body = this.getMessageBody(message);
const delayed = !_.isNull(delay), const { _converse } = this.__super__,
is_groupchat = type === 'groupchat', { __ } = _converse,
chat_state = message.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING || spoiler = message.querySelector(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`),
message.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED || chat_state = message.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING ||
message.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE || message.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED ||
message.getElementsByTagName(_converse.ACTIVE).length && _converse.ACTIVE || message.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE ||
message.getElementsByTagName(_converse.GONE).length && _converse.GONE; message.getElementsByTagName(_converse.ACTIVE).length && _converse.ACTIVE ||
message.getElementsByTagName(_converse.GONE).length && _converse.GONE;
let from;
if (is_groupchat) {
from = Strophe.unescapeNode(Strophe.getResourceFromJid(message.getAttribute('from')));
} else {
from = Strophe.getBareJidFromJid(message.getAttribute('from'));
}
const time = delayed ? delay.getAttribute('stamp') : moment().format();
let sender, fullname;
if ((is_groupchat && from === this.get('nick')) || (!is_groupchat && from === _converse.bare_jid)) {
sender = 'me';
fullname = _converse.xmppstatus.get('fullname');
} else {
sender = 'them';
fullname = this.get('fullname');
}
const spoiler = message.querySelector(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`);
const attrs = { const attrs = {
'type': type, 'type': message.getAttribute('type'),
'from': from,
'chat_state': chat_state, 'chat_state': chat_state,
'delayed': delayed, 'delayed': !_.isNull(delay),
'fullname': fullname, 'message': this.getMessageBody(message) || undefined,
'message': body || undefined,
'msgid': message.getAttribute('id'), 'msgid': message.getAttribute('id'),
'sender': sender, 'time': delay ? delay.getAttribute('stamp') : moment().format(),
'time': time,
'is_spoiler': !_.isNull(spoiler) 'is_spoiler': !_.isNull(spoiler)
}; };
if (attrs.type === 'groupchat') {
attrs.from = message.getAttribute('from');
attrs.nick = Strophe.unescapeNode(Strophe.getResourceFromJid(attrs.from));
attrs.username = attrs.nick;
if (attrs.from === this.get('nick')) {
attrs.sender = 'me';
} else {
attrs.sender = 'them';
}
} else {
attrs.from = Strophe.getBareJidFromJid(message.getAttribute('from'));
if (attrs.from === _converse.bare_jid) {
attrs.sender = 'me';
attrs.fullname = _converse.xmppstatus.get('fullname');
attrs.username = attrs.fullname || attrs.from;
} else {
attrs.sender = 'them';
attrs.fullname = this.get('fullname');
attrs.username = attrs.fullname || attrs.from;
}
}
_.each(sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, message), (xform) => { _.each(sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, message), (xform) => {
attrs['oob_url'] = xform.querySelector('url').textContent; attrs['oob_url'] = xform.querySelector('url').textContent;
attrs['oob_desc'] = xform.querySelector('url').textContent; attrs['oob_desc'] = xform.querySelector('url').textContent;

View File

@ -579,14 +579,14 @@
return this.scrollDown(); return this.scrollDown();
}, },
clearChatStateNotification (from, isodate) { clearChatStateNotification (username, isodate) {
if (isodate) { if (isodate) {
_.each( _.each(
sizzle(`.chat-state-notification[data-csn="${from}"][data-isodate="${isodate}"]`, this.content), sizzle(`.chat-state-notification[data-csn="${username}"][data-isodate="${isodate}"]`, this.content),
u.removeElement u.removeElement
); );
} else { } else {
_.each(sizzle(`.chat-state-notification[data-csn="${from}"]`, this.content), u.removeElement); _.each(sizzle(`.chat-state-notification[data-csn="${username}"]`, this.content), u.removeElement);
} }
}, },
@ -594,9 +594,8 @@
/* Support for XEP-0085, Chat State Notifications */ /* Support for XEP-0085, Chat State Notifications */
let text; let text;
const from = message.get('from'), const from = message.get('from'),
username = message.get('fullname') || from, username = message.get('username');
data = `data-csn=${from}`; this.clearChatStateNotification(username);
this.clearChatStateNotification(from);
if (message.get('chat_state') === _converse.COMPOSING) { if (message.get('chat_state') === _converse.COMPOSING) {
if (message.get('sender') === 'me') { if (message.get('sender') === 'me') {
@ -619,6 +618,7 @@
this.content.insertAdjacentHTML( this.content.insertAdjacentHTML(
'beforeend', 'beforeend',
tpl_csn({ tpl_csn({
'username': username,
'message': text, 'message': text,
'from': from, 'from': from,
'isodate': isodate 'isodate': isodate
@ -626,7 +626,7 @@
this.scrollDown(); this.scrollDown();
this.clear_status_timeout = window.setTimeout( this.clear_status_timeout = window.setTimeout(
this.clearChatStateNotification.bind(this, from, isodate), this.clearChatStateNotification.bind(this, username, isodate),
30000 30000
); );
return message; return message;
@ -717,7 +717,7 @@
const view = new _converse.MessageView({'model': message}); const view = new _converse.MessageView({'model': message});
this.insertMessage(view); this.insertMessage(view);
this.insertDayIndicator(view.el); this.insertDayIndicator(view.el);
this.clearChatStateNotification(message.get('from')); this.clearChatStateNotification(message.get('username'));
this.setScrollPosition(view.el); this.setScrollPosition(view.el);
if (u.isNewMessage(message)) { if (u.isNewMessage(message)) {

View File

@ -45,8 +45,14 @@
initialize () { initialize () {
this.chatbox = this.model.collection.chatbox; this.chatbox = this.model.collection.chatbox;
this.chatbox.on('change:fullname', (chatbox) => this.model.save('fullname', chatbox.get('fullname'))); this.chatbox.on('change:fullname', (chatbox) => {
if (chatbox.get('type') !== 'chatroom') {
this.model.save({
'fullname': chatbox.get('fullname'),
'username': chatbox.get('fullname')
})
}
});
this.model.on('change:fullname', this.render, this); this.model.on('change:fullname', this.render, this);
this.model.on('change:progress', this.renderFileUploadProgresBar, this); this.model.on('change:progress', this.renderFileUploadProgresBar, this);
this.model.on('change:type', this.render, this); this.model.on('change:type', this.render, this);
@ -60,18 +66,13 @@
} else if (this.model.get('type') === 'error') { } else if (this.model.get('type') === 'error') {
return this.renderErrorMessage(); return this.renderErrorMessage();
} }
let template, image, image_type,
let template, username, image, image_type,
text = this.model.get('message'); text = this.model.get('message');
// TODO: store proper username on the message itself
if (this.isMeCommand()) { if (this.isMeCommand()) {
const arr = this.getValuesForMeCommand(); template = tpl_action;
template = arr[0]; text = this.model.get('message').replace(/^\/me/, '');
username = arr[1];
text = arr[2];
} else { } else {
username = this.model.get('fullname') || this.model.get('from');
template = this.model.get('is_spoiler') ? tpl_spoiler_message : tpl_message; template = this.model.get('is_spoiler') ? tpl_spoiler_message : tpl_message;
if (this.model.get('type') !== 'headline') { if (this.model.get('type') !== 'headline') {
if (this.model.get('sender') === 'me') { if (this.model.get('sender') === 'me') {
@ -88,7 +89,6 @@
_.extend(this.model.toJSON(), { _.extend(this.model.toJSON(), {
'pretty_time': moment_time.format(_converse.time_format), 'pretty_time': moment_time.format(_converse.time_format),
'time': moment_time.format(), 'time': moment_time.format(),
'username': username,
'extra_classes': this.getExtraMessageClasses(), 'extra_classes': this.getExtraMessageClasses(),
'label_show': __('Show more'), 'label_show': __('Show more'),
'image_type': image_type, 'image_type': image_type,
@ -168,21 +168,6 @@
return match && match[1] === 'me'; return match && match[1] === 'me';
}, },
getValuesForMeCommand() {
let username, text;
const match = this.model.get('message').match(/^\/(.*?)(?: (.*))?$/);
if (match && match[1] === 'me') {
text = this.model.get('message').replace(/^\/me/, '');
}
if (this.model.get('sender') === 'me') {
const fullname = _converse.xmppstatus.get('fullname') || this.model.get('fullname');
username = _.isNil(fullname) ? _converse.bare_jid : fullname;
} else {
username = this.model.get('fullname') || this.model.get('from');
}
return [tpl_action, username, text]
},
processMessageText () { processMessageText () {
var text = this.get('message'); var text = this.get('message');
text = u.geoUriToHttp(text, _converse.geouri_replacement); text = u.geoUriToHttp(text, _converse.geouri_replacement);

View File

@ -305,6 +305,7 @@
const is_spoiler = this.get('composing_spoiler'); const is_spoiler = this.get('composing_spoiler');
return { return {
'fullname': this.get('nick'), 'fullname': this.get('nick'),
'username': this.get('nick'),
'is_spoiler': is_spoiler, 'is_spoiler': is_spoiler,
'message': text ? u.httpToGeoUri(emojione.shortnameToUnicode(text), _converse) : undefined, 'message': text ? u.httpToGeoUri(emojione.shortnameToUnicode(text), _converse) : undefined,
'sender': 'me', 'sender': 'me',

View File

@ -1,3 +1,3 @@
<div class="message chat-info chat-state-notification" <div class="message chat-info chat-state-notification"
data-isodate="{{{o.isodate}}}" data-isodate="{{{o.isodate}}}"
data-csn="{{{o.from}}}">{{{o.message}}}</div> data-csn="{{{o.username}}}">{{{o.message}}}</div>