Commit 6ac1df43 authored by JC Brand's avatar JC Brand

Render chat state notifications on the message view

and not via the chatbox view (fixes some failing tests also).
parent 99915a26
......@@ -718,25 +718,30 @@
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
var chatboxview = _converse.chatboxviews.get(sender_jid);
expect(chatboxview).toBeDefined();
// Check that the notification appears inside the chatbox in the DOM
var events = chatboxview.el.querySelectorAll('.chat-state-notification');
expect(events.length).toBe(1);
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
// Check that it doesn't appear twice
msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
events = chatboxview.el.querySelectorAll('.chat-state-notification');
expect(events.length).toBe(1);
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
done();
var view = _converse.chatboxviews.get(sender_jid);
expect(view).toBeDefined();
test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
.then(function () {
var view = _converse.chatboxviews.get(sender_jid);
// Check that the notification appears inside the chatbox in the DOM
var events = view.el.querySelectorAll('.chat-state-notification');
expect(events.length).toBe(1);
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
// Check that it doesn't appear twice
msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
events = view.el.querySelectorAll('.chat-state-notification');
expect(events.length).toBe(1);
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
done();
})
}));
it("can be a composing carbon message that this user sent from a different client",
......@@ -877,10 +882,14 @@
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
var chatboxview = _converse.chatboxviews.get(sender_jid);
var $events = $(chatboxview.el).find('.chat-info.chat-state-notification');
expect($events.text()).toEqual(mock.cur_names[1] + ' has stopped typing');
done();
var view = _converse.chatboxviews.get(sender_jid);
test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
.then(function () {
var view = _converse.chatboxviews.get(sender_jid);
var event = view.el.querySelector('.chat-info.chat-state-notification');
expect(event.textContent).toEqual(mock.cur_names[1] + ' has stopped typing');
done();
});
});
}));
......@@ -1113,10 +1122,14 @@
}).c('body').c('gone', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
var chatboxview = _converse.chatboxviews.get(sender_jid);
var $events = $(chatboxview.el).find('.chat-state-notification');
expect($events.text()).toEqual(mock.cur_names[1] + ' has gone away');
done();
var view = _converse.chatboxviews.get(sender_jid);
test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
.then(function () {
var view = _converse.chatboxviews.get(sender_jid);
var event = view.el.querySelector('.chat-state-notification');
expect(event.textContent).toEqual(mock.cur_names[1] + ' has gone away');
done();
});
}));
});
});
......
......@@ -109,6 +109,16 @@
this.getRequestSlotURL();
}
}
if (this.isOnlyChatStateNotification()) {
window.setTimeout(this.destroy.bind(this), 20000);
}
},
isOnlyChatStateNotification () {
return this.get('chat_state') &&
!this.get('oob_url') &&
!this.get('file') &&
!this.get('message');
},
getDisplayName () {
......
......@@ -14,7 +14,6 @@
"tpl!chatbox",
"tpl!chatbox_head",
"tpl!chatbox_message_form",
"tpl!csn",
"tpl!emojis",
"tpl!error_message",
"tpl!help_message",
......@@ -37,7 +36,6 @@
tpl_chatbox,
tpl_chatbox_head,
tpl_chatbox_message_form,
tpl_csn,
tpl_emojis,
tpl_error_message,
tpl_help_message,
......@@ -589,48 +587,6 @@
}
},
showChatStateNotification (message) {
/* Support for XEP-0085, Chat State Notifications */
let text;
const from = message.get('from'),
name = message.getDisplayName();
this.clearChatStateNotification(message);
if (message.get('chat_state') === _converse.COMPOSING) {
if (message.get('sender') === 'me') {
text = __('Typing from another device');
} else {
text = name +' '+__('is typing');
}
} else if (message.get('chat_state') === _converse.PAUSED) {
if (message.get('sender') === 'me') {
text = __('Stopped typing on the other device');
} else {
text = name +' '+__('has stopped typing');
}
} else if (message.get('chat_state') === _converse.GONE) {
text = name +' '+__('has gone away');
} else {
return;
}
const isodate = moment().format();
this.content.insertAdjacentHTML(
'beforeend',
tpl_csn({
'message': text,
'from': from,
'isodate': isodate
}));
this.scrollDown();
this.clear_status_timeout = window.setTimeout(
this.clearChatStateNotification.bind(this, message, isodate),
30000
);
return message;
},
shouldShowOnTextMessage () {
return !u.isVisible(this.el);
},
......@@ -711,9 +667,9 @@
* (Backbone.Model) message: The message object
*/
const view = new _converse.MessageView({'model': message});
this.clearChatStateNotification(message);
this.insertMessage(view);
this.insertDayIndicator(view.el);
this.clearChatStateNotification(message);
this.setScrollPosition(view.el);
if (u.isNewMessage(message)) {
......@@ -740,20 +696,8 @@
* Parameters:
* (Object) message - The message Backbone object that was added.
*/
if (!_.isUndefined(this.clear_status_timeout)) {
window.clearTimeout(this.clear_status_timeout);
delete this.clear_status_timeout;
}
if (message.get('type') === 'error') {
this.showMessage(message);
} else {
if (message.get('chat_state') && !message.get('delayed')) {
this.showChatStateNotification(message);
}
if (message.get('file') || message.get('message')) {
this.showMessage(message);
}
}
this.showMessage(message);
_converse.emit('messageAdded', {
'message': message,
'chatbox': this.model
......
......@@ -11,6 +11,7 @@
"emojione",
"filesize",
"tpl!action",
"tpl!csn",
"tpl!file_progress",
"tpl!info",
"tpl!message",
......@@ -22,6 +23,7 @@
emojione,
filesize,
tpl_action,
tpl_csn,
tpl_file_progress,
tpl_info,
tpl_message,
......@@ -74,15 +76,31 @@
this.model.on('change:progress', this.renderFileUploadProgresBar, this);
this.model.on('change:type', this.render, this);
this.model.on('change:upload', this.render, this);
this.model.on('destroy', this.remove, this);
this.render();
},
render () {
if (this.model.get('file') && !this.model.get('oob_url')) {
if (this.model.isOnlyChatStateNotification()) {
return this.renderChatStateNotification()
} else if (this.model.get('file') && !this.model.get('oob_url')) {
return this.renderFileUploadProgresBar();
} else if (this.model.get('type') === 'error') {
return this.renderErrorMessage();
} else {
return this.renderChatMessage();
}
},
replaceElement (msg) {
if (!_.isNil(this.el.parentElement)) {
this.el.parentElement.replaceChild(msg, this.el);
}
this.setElement(msg);
return this.el;
},
renderChatMessage () {
let template, text = this.model.get('message');
if (this.isMeCommand()) {
template = tpl_action;
......@@ -104,13 +122,11 @@
var url = this.model.get('oob_url');
if (url) {
const msg_media = msg.querySelector('.chat-msg-media');
msg_media.innerHTML = _.flow(
msg.querySelector('.chat-msg-media').innerHTML = _.flow(
_.partial(u.renderFileURL, _converse),
_.partial(u.renderMovieURL, _converse),
_.partial(u.renderAudioURL, _converse),
_.partial(u.renderImageURL, _converse)
)(url);
_.partial(u.renderImageURL, _converse))(url);
}
const msg_content = msg.querySelector('.chat-msg-text');
......@@ -126,19 +142,12 @@
this.model.collection.trigger('rendered');
});
this.replaceElement(msg);
if (this.model.get('type') !== 'headline') {
this.renderAvatar();
}
},
replaceElement (msg) {
if (!_.isNil(this.el.parentElement)) {
this.el.parentElement.replaceChild(msg, this.el);
}
this.setElement(msg);
return this.el;
},
renderErrorMessage () {
const moment_time = moment(this.model.get('time')),
msg = u.stringToElement(
......@@ -150,6 +159,41 @@
return this.replaceElement(msg);
},
renderChatStateNotification () {
if (this.model.get('delayed')) {
return this.model.destroy();
}
let text;
const from = this.model.get('from'),
name = this.model.getDisplayName();
if (this.model.get('chat_state') === _converse.COMPOSING) {
if (this.model.get('sender') === 'me') {
text = __('Typing from another device');
} else {
text = name +' '+__('is typing');
}
} else if (this.model.get('chat_state') === _converse.PAUSED) {
if (this.model.get('sender') === 'me') {
text = __('Stopped typing on the other device');
} else {
text = name +' '+__('has stopped typing');
}
} else if (this.model.get('chat_state') === _converse.GONE) {
text = name +' '+__('has gone away');
} else {
return;
}
const isodate = moment().format();
this.replaceElement(
u.stringToElement(
tpl_csn({
'message': text,
'from': from,
'isodate': isodate
})));
},
renderFileUploadProgresBar () {
const msg = u.stringToElement(tpl_file_progress(
_.extend(this.model.toJSON(), {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment