converse-mam: Use API internally

This commit is contained in:
JC Brand 2018-01-16 12:20:18 +01:00
parent a1767ffecd
commit 93da96ad91

View File

@ -36,6 +36,83 @@
} }
} }
function queryForArchivedMessages (_converse, options, callback, errback) {
/* Internal function, called by the "archive.query" API method.
*/
let date;
if (_.isFunction(options)) {
callback = options;
errback = callback;
}
const queryid = _converse.connection.getUniqueId();
const attrs = {'type':'set'};
if (!_.isUndefined(options) && options.groupchat) {
if (!options['with']) { // eslint-disable-line dot-notation
throw new Error(
'You need to specify a "with" value containing '+
'the chat room JID, when querying groupchat messages.');
}
attrs.to = options['with']; // eslint-disable-line dot-notation
}
const stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
if (!_.isUndefined(options)) {
stanza.c('x', {'xmlns':Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var':'FORM_TYPE', 'type': 'hidden'})
.c('value').t(Strophe.NS.MAM).up().up();
if (options['with'] && !options.groupchat) { // eslint-disable-line dot-notation
stanza.c('field', {'var':'with'}).c('value')
.t(options['with']).up().up(); // eslint-disable-line dot-notation
}
_.each(['start', 'end'], function (t) {
if (options[t]) {
date = moment(options[t]);
if (date.isValid()) {
stanza.c('field', {'var':t}).c('value').t(date.format()).up().up();
} else {
throw new TypeError(`archive.query: invalid date provided for: ${t}`);
}
}
});
stanza.up();
if (options instanceof Strophe.RSM) {
stanza.cnode(options.toXML());
} else if (_.intersection(RSM_ATTRIBUTES, _.keys(options)).length) {
stanza.cnode(new Strophe.RSM(options).toXML());
}
}
const messages = [];
const message_handler = _converse.connection.addHandler(function (message) {
const result = message.querySelector('result');
if (!_.isNull(result) && result.getAttribute('queryid') === queryid) {
messages.push(message);
}
return true;
}, Strophe.NS.MAM);
_converse.connection.sendIQ(
stanza,
function (iq) {
_converse.connection.deleteHandler(message_handler);
if (_.isFunction(callback)) {
const set = iq.querySelector('set');
let rsm;
if (!_.isUndefined(set)) {
rsm = new Strophe.RSM({xml: set});
_.extend(rsm, _.pick(options, _.concat(MAM_ATTRIBUTES, ['max'])));
}
callback(messages, rsm);
}
},
function () {
_converse.connection.deleteHandler(message_handler);
if (_.isFunction(errback)) { errback.apply(this, arguments); }
},
_converse.message_archiving_timeout
);
}
converse.plugins.add('converse-mam', { converse.plugins.add('converse-mam', {
@ -150,7 +227,7 @@
return; return;
} }
this.addSpinner(); this.addSpinner();
_converse.queryForArchivedMessages( _converse.api.archive.query(
_.extend({ _.extend({
'before': '', // Page backwards from the most recent message 'before': '', // Page backwards from the most recent message
'max': _converse.archived_messages_page_size, 'max': _converse.archived_messages_page_size,
@ -283,97 +360,6 @@
message_archiving_timeout: 8000, // Time (in milliseconds) to wait before aborting MAM request message_archiving_timeout: 8000, // Time (in milliseconds) to wait before aborting MAM request
}); });
_converse.queryForArchivedMessages = function (options, callback, errback) {
/* Do a MAM (XEP-0313) query for archived messages.
*
* Parameters:
* (Object) options - Query parameters, either MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever we receive query-relevant stanza.
* (Function) errback - A function to call when an error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* The callback function may be called multiple times, first
* for the initial IQ result and then for each message
* returned. The last time the callback is called, a
* Strophe.RSM object is returned on which "next" or "previous"
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
let date;
if (_.isFunction(options)) {
callback = options;
errback = callback;
}
const queryid = _converse.connection.getUniqueId();
const attrs = {'type':'set'};
if (!_.isUndefined(options) && options.groupchat) {
if (!options['with']) { // eslint-disable-line dot-notation
throw new Error(
'You need to specify a "with" value containing '+
'the chat room JID, when querying groupchat messages.');
}
attrs.to = options['with']; // eslint-disable-line dot-notation
}
const stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
if (!_.isUndefined(options)) {
stanza.c('x', {'xmlns':Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var':'FORM_TYPE', 'type': 'hidden'})
.c('value').t(Strophe.NS.MAM).up().up();
if (options['with'] && !options.groupchat) { // eslint-disable-line dot-notation
stanza.c('field', {'var':'with'}).c('value')
.t(options['with']).up().up(); // eslint-disable-line dot-notation
}
_.each(['start', 'end'], function (t) {
if (options[t]) {
date = moment(options[t]);
if (date.isValid()) {
stanza.c('field', {'var':t}).c('value').t(date.format()).up().up();
} else {
throw new TypeError(`archive.query: invalid date provided for: ${t}`);
}
}
});
stanza.up();
if (options instanceof Strophe.RSM) {
stanza.cnode(options.toXML());
} else if (_.intersection(RSM_ATTRIBUTES, _.keys(options)).length) {
stanza.cnode(new Strophe.RSM(options).toXML());
}
}
const messages = [];
const message_handler = _converse.connection.addHandler(function (message) {
const result = message.querySelector('result');
if (!_.isNull(result) && result.getAttribute('queryid') === queryid) {
messages.push(message);
}
return true;
}, Strophe.NS.MAM);
_converse.connection.sendIQ(
stanza,
function (iq) {
_converse.connection.deleteHandler(message_handler);
if (_.isFunction(callback)) {
const set = iq.querySelector('set');
let rsm;
if (!_.isUndefined(set)) {
rsm = new Strophe.RSM({xml: set});
_.extend(rsm, _.pick(options, _.concat(MAM_ATTRIBUTES, ['max'])));
}
callback(messages, rsm);
}
},
function () {
_converse.connection.deleteHandler(message_handler);
if (_.isFunction(errback)) { errback.apply(this, arguments); }
},
_converse.message_archiving_timeout
);
};
_converse.onMAMError = function (iq) { _converse.onMAMError = function (iq) {
if (iq.querySelectorAll('feature-not-implemented').length) { if (iq.querySelectorAll('feature-not-implemented').length) {
@ -457,11 +443,29 @@
/* Extend default converse.js API to add methods specific to MAM /* Extend default converse.js API to add methods specific to MAM
*/ */
'archive': { 'archive': {
'query': function () { 'query': function (options, callback, errback) {
/* Do a MAM (XEP-0313) query for archived messages.
*
* Parameters:
* (Object) options - Query parameters, either
* MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever
* we receive query-relevant stanza.
* (Function) errback - A function to call when an
* error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* When the the callback is called, a Strophe.RSM object is
* returned on which "next" or "previous" can be called
* before passing it in again to this method, to
* get the next or previous page in the result set.
*/
if (!_converse.api.connection.connected()) { if (!_converse.api.connection.connected()) {
throw new Error('Can\'t call `api.archive.query` before having established an XMPP session'); throw new Error('Can\'t call `api.archive.query` before having established an XMPP session');
} }
return _converse.queryForArchivedMessages.apply(this, arguments); return queryForArchivedMessages(_converse, options, callback, errback);
} }
} }
}); });