Commit 133df99a authored by JC Brand's avatar JC Brand

Honor the filesize restrictions of the XMPP server

updates #161
parent 95e648e7
......@@ -1929,6 +1929,12 @@
"integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
"dev": true
},
"filesize": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
"integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==",
"dev": true
},
"fill-range": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
......
......@@ -765,7 +765,7 @@
// We send another message, for which an error will
// not be received, to test that errors appear
// after the relevant message.
msg_text = 'This message will be sent, and not receive an error';
msg_text = 'This message will be sent, and also receive an error';
message = view.model.messages.create({
'msgid': '6fcdeee3-000f-4ce8-a17e-9ce28f0ae104',
'fullname': fullname,
......@@ -802,12 +802,6 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').text()).toEqual(error_txt);
/* Incoming error messages that are not tied to a
* certain show message (via the msgid attribute),
* are not shown at all. The reason for this is
* that we may get error messages for chat state
* notifications as well.
*/
stanza = $msg({
'to': _converse.connection.jid,
'type':'error',
......@@ -819,7 +813,36 @@
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
.t('Server-to-server connection failed: Connecting failed: connection timeout');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').length).toEqual(1);
expect($chat_content.find('.chat-error').length).toEqual(2);
// If the last message is already an error message,
// then we don't render it another time.
stanza = $msg({
'to': _converse.connection.jid,
'type':'error',
'id':'another-unused-id',
'from': sender_jid
})
.c('error', {'type': 'cancel'})
.c('remote-server-not-found', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" }).up()
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
.t('Server-to-server connection failed: Connecting failed: connection timeout');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').length).toEqual(2);
// A different error message will however render
stanza = $msg({
'to': _converse.connection.jid,
'type':'error',
'id':'another-id',
'from': sender_jid
})
.c('error', {'type': 'cancel'})
.c('remote-server-not-found', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" }).up()
.c('text', { 'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas" })
.t('Something else went wrong as well');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect($chat_content.find('.chat-error').length).toEqual(3);
done();
}));
});
......
This diff is collapsed.
......@@ -29,6 +29,7 @@ require.config({
"emojione": "node_modules/emojione/lib/js/emojione",
"es6-promise": "node_modules/es6-promise/dist/es6-promise.auto",
"eventemitter": "node_modules/otr/build/dep/eventemitter",
"filesize": "node_modules/filesize/lib/filesize",
"form-utils": "src/utils/form",
"i18n": "src/i18n",
"jed": "node_modules/jed/jed",
......
......@@ -8,10 +8,11 @@
define([
"converse-core",
"emojione",
"filesize",
"tpl!chatboxes",
"backbone.overview"
], factory);
}(this, function (converse, emojione, tpl_chatboxes) {
}(this, function (converse, emojione, filesize, tpl_chatboxes) {
"use strict";
const { $msg, Backbone, Promise, Strophe, b64_sha1, moment, utils, _ } = converse.env;
......@@ -289,21 +290,36 @@
sendFiles (files) {
_converse.api.disco.supports(Strophe.NS.HTTPUPLOAD, _converse.domain).then((result) => {
const slot_request_url = _.get(result.pop(), 'id');
const item = result.pop(),
data = item.dataforms.where({'FORM_TYPE': {'value': Strophe.NS.HTTPUPLOAD, 'type': "hidden"}}).pop(),
max_file_size = window.parseInt(_.get(data, 'attributes.max-file-size.value')),
slot_request_url = _.get(item, 'id');
if (!slot_request_url) {
const err_msg = __("Sorry, looks like file upload is not supported by your server.");
return this.trigger('showHelpMessages', [err_msg], 'error');
this.messages.create({
'message': __("Sorry, looks like file upload is not supported by your server."),
'type': 'error',
});
return;
}
_.each(files, (file) => {
this.messages.create(
_.extend(
this.getOutgoingMessageAttributes(), {
'file': file,
'progress': 0,
'slot_request_url': slot_request_url,
'type': this.get('message_type'),
})
);
if (!window.isNaN(max_file_size) && window.parseInt(file.size) > max_file_size) {
return this.messages.create({
'message': __('The size of your file, %1$s, exceeds the maximum allowed by your server, which is %2$s.',
file.name, filesize(max_file_size)),
'type': 'error',
});
} else {
this.messages.create(
_.extend(
this.getOutgoingMessageAttributes(), {
'file': file,
'progress': 0,
'slot_request_url': slot_request_url,
'type': this.get('message_type'),
})
);
}
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
},
......
......@@ -529,33 +529,6 @@
}
},
showMessage (message) {
/* Inserts a chat message into the content area of the chat box.
* Will also insert a new day indicator if the message is on a
* different day.
*
* The message to show may either be newer than the newest
* message, or older than the oldest message.
*
* Parameters:
* (Backbone.Model) message: The message object
*/
const view = new _converse.MessageView({'model': message}),
current_msg_date = moment(message.get('time')) || moment,
previous_msg_date = this.getLastMessageDate(current_msg_date),
message_el = view.el;
if (_.isNull(previous_msg_date)) {
this.content.insertAdjacentElement('afterbegin', message_el);
} else {
const previous_msg_el = sizzle(`[data-isodate="${previous_msg_date}"]:last`, this.content).pop();
previous_msg_el.insertAdjacentElement('afterend', message_el);
}
this.insertDayIndicator(message_el);
this.clearChatStateNotification(message.get('from'));
this.setScrollPosition(message_el);
},
setScrollPosition (message_el) {
/* Given a newly inserted message, determine whether we
* should keep the scrollbar in place (so as to not scroll
......@@ -655,8 +628,50 @@
return !u.isVisible(this.el);
},
handleTextMessage (message) {
this.showMessage(message);
insertMessage (view) {
/* Given a view representing a message, insert it inot the
* content area of the chat box.
*
* Parameters:
* (Backbone.View) message: The message Backbone.View
*/
if (view.model.get('type') === 'error') {
const previous_msg_el = this.content.querySelector(`[data-msgid="${view.model.get('msgid')}"]`);
if (previous_msg_el) {
return previous_msg_el.insertAdjacentElement('afterend', view.el);
}
}
const current_msg_date = moment(view.model.get('time')) || moment,
previous_msg_date = this.getLastMessageDate(current_msg_date);
if (_.isNull(previous_msg_date)) {
this.content.insertAdjacentElement('afterbegin', view.el);
} else {
const previous_msg_el = sizzle(`[data-isodate="${previous_msg_date}"]:last`, this.content).pop();
if (view.model.get('type') === 'error' &&
u.hasClass('chat-error', previous_msg_el) &&
previous_msg_el.textContent === view.model.get('message')) {
// We don't show a duplicate error message
return;
}
previous_msg_el.insertAdjacentElement('afterend', view.el);
}
},
showMessage (message) {
/* Inserts a chat message into the content area of the chat box.
*
* Will also insert a new day indicator if the message is on a
* different day.
*
* Parameters:
* (Backbone.Model) message: The message object
*/
const view = new _converse.MessageView({'model': message});
this.insertMessage(view);
this.insertDayIndicator(view.el);
this.clearChatStateNotification(message.get('from'));
this.setScrollPosition(view.el);
if (u.isNewMessage(message)) {
if (message.get('sender') === 'me') {
......@@ -676,21 +691,6 @@
}
},
handleErrorMessage (message) {
const message_el = this.content.querySelector(`[data-msgid="${message.get('msgid')}"]`);
if (!_.isNull(message_el)) {
message_el.insertAdjacentHTML(
'afterend',
tpl_info({
'extra_classes': 'chat-error',
'message': message.get('message'),
'isodate': moment().format(),
'data': ''
}));
this.scrollDown();
}
},
onMessageAdded (message) {
/* Handler that gets called when a new message object is created.
*
......@@ -702,13 +702,13 @@
delete this.clear_status_timeout;
}
if (message.get('type') === 'error') {
this.handleErrorMessage(message);
this.showMessage(message);
} else {
if (message.get('chat_state')) {
this.showChatStateNotification(message);
}
if (message.get('file') || message.get('message')) {
this.handleTextMessage(message);
this.showMessage(message);
}
}
_converse.emit('messageAdded', {
......
......@@ -11,6 +11,7 @@
"emojione",
"tpl!action",
"tpl!file",
"tpl!info",
"tpl!message",
"tpl!spoiler_message"
], factory);
......@@ -20,6 +21,7 @@
emojione,
tpl_action,
tpl_file,
tpl_info,
tpl_message,
tpl_spoiler_message
) {
......@@ -53,7 +55,10 @@
render () {
if (this.model.get('file') && !this.model.get('message')) {
return this.renderFileUploadProgresBar();
} else if (this.model.get('type') === 'error') {
return this.renderErrorMessage();
}
let template, username,
text = this.model.get('message');
......@@ -91,6 +96,10 @@
u.renderImageURLs(msg_content).then(() => {
this.model.collection.trigger('rendered');
});
return this.replaceElement(msg);
},
replaceElement (msg) {
if (!_.isNil(this.el.parentElement)) {
this.el.parentElement.replaceChild(msg, this.el);
}
......@@ -98,13 +107,20 @@
return this.el;
},
renderErrorMessage () {
const moment_time = moment(this.model.get('time')),
msg = u.stringToElement(
tpl_info(_.extend(this.model.toJSON(), {
'extra_classes': 'chat-error',
'isodate': moment_time.format(),
'data': ''
})));
return this.replaceElement(msg);
},
renderFileUploadProgresBar () {
const msg = u.stringToElement(tpl_file(this.model.toJSON()));
if (!_.isNil(this.el.parentElement)) {
this.el.parentElement.replaceChild(msg, this.el);
}
this.setElement(msg);
return this.el;
return this.replaceElement(msg);
},
isMeCommand () {
......
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