Commit c0f30962 authored by JC Brand's avatar JC Brand

Move MAM view overrides and view-based code out of @converse/headless

updates #1352
parent 11c1b016
This diff is collapsed.
// Converse.js (A browser based XMPP chat client)
// https://conversejs.org
//
// Copyright (c) 2012-2019, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
// Views for XEP-0313 Message Archive Management
import converse from "@converse/headless/converse-core";
const CHATROOMS_TYPE = 'chatroom';
const { Strophe, _ } = converse.env;
const u = converse.env.utils;
converse.plugins.add('converse-mam-views', {
dependencies: ['converse-disco', 'converse-mam', 'converse-chatview', 'converse-muc-views'],
overrides: {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatBoxView: {
render () {
const result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchNewestMessages () {
/* Fetches messages that might have been archived *after*
* the last archived message in our local cache.
*/
if (this.disable_mam) { return; }
const { _converse } = this.__super__,
most_recent_msg = u.getMostRecentMessage(this.model);
if (_.isNil(most_recent_msg)) {
this.fetchArchivedMessages();
} else {
const stanza_id = most_recent_msg.get(`stanza_id ${this.model.get('jid')}`);
if (stanza_id) {
this.fetchArchivedMessages({'after': stanza_id});
} else {
this.fetchArchivedMessages({'start': most_recent_msg.get('time')});
}
}
},
fetchArchivedMessagesIfNecessary () {
/* Check if archived messages should be fetched, and if so, do so. */
if (this.disable_mam || this.model.get('mam_initialized')) {
return;
}
const { _converse } = this.__super__;
_converse.api.disco.supports(Strophe.NS.MAM, _converse.bare_jid).then(
(result) => { // Success
if (result.length) {
this.fetchArchivedMessages();
}
this.model.save({'mam_initialized': true});
},
() => { // Error
_converse.log(
"Error or timeout while checking for MAM support",
Strophe.LogLevel.ERROR
);
}
).catch((msg) => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
fetchArchivedMessages (options) {
const { _converse } = this.__super__;
if (this.disable_mam) { return; }
const is_groupchat = this.model.get('type') === CHATROOMS_TYPE;
let mam_jid, message_handler;
if (is_groupchat) {
mam_jid = this.model.get('jid');
message_handler = this.model.onMessage.bind(this.model);
} else {
mam_jid = _converse.bare_jid;
message_handler = _converse.chatboxes.onMessage.bind(_converse.chatboxes)
}
_converse.api.disco.supports(Strophe.NS.MAM, mam_jid).then(
(results) => { // Success
if (!results.length) { return; }
this.addSpinner();
_converse.api.archive.query(
// TODO: only query from the last message we have
// in our history
_.extend({
'groupchat': is_groupchat,
'before': '', // Page backwards from the most recent message
'max': _converse.archived_messages_page_size,
'with': this.model.get('jid'),
}, options),
(messages) => { // Success
this.clearSpinner();
_.each(messages, message_handler);
},
e => { // Error
this.clearSpinner();
_converse.log(
"Error or timeout while trying to fetch "+
"archived messages", Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
}
);
},
() => { // Error
_converse.log(
"Error or timeout while checking for MAM support",
Strophe.LogLevel.ERROR
);
}
).catch((msg) => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
onScroll (ev) {
const { _converse } = this.__super__;
if (this.content.scrollTop === 0 && this.model.messages.length) {
const oldest_message = this.model.messages.at(0);
const by_jid = this.model.get('jid');
const stanza_id = oldest_message.get(`stanza_id ${by_jid}`);
if (stanza_id) {
this.fetchArchivedMessages({'before': stanza_id});
} else {
this.fetchArchivedMessages({
'end': oldest_message.get('time')
});
}
}
},
},
ChatRoomView: {
initialize () {
const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:mam_enabled', this.fetchArchivedMessagesIfNecessary, this);
this.model.on('change:connection_status', this.fetchArchivedMessagesIfNecessary, this);
},
renderChatArea () {
const result = this.__super__.renderChatArea.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchArchivedMessagesIfNecessary () {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED ||
!this.model.get('mam_enabled') ||
this.model.get('mam_initialized')) {
return;
}
this.fetchArchivedMessages();
this.model.save({'mam_initialized': true});
}
}
},
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const { _converse } = this;
/* Event handlers */
_converse.on('afterMessagesFetched', view => view.fetchNewestMessages());
_converse.on('reconnected', () => {
const private_chats = _converse.chatboxviews.filter(
view => _.at(view, 'model.attributes.type')[0] === 'chatbox'
);
_.each(private_chats, (view) => view.fetchNewestMessages())
});
}
});
......@@ -15,6 +15,7 @@ import "converse-dragresize"; // Allows chat boxes to be resized by draggin
import "converse-embedded";
import "converse-fullscreen";
import "converse-headline"; // Support for headline messages
import "converse-mam-views";
import "converse-minimize"; // Allows chat boxes to be minimized
import "converse-muc-views"; // Views related to MUC
import "converse-notification"; // HTML5 Notifications
......@@ -38,6 +39,7 @@ const WHITELISTED_PLUGINS = [
'converse-embedded',
'converse-fullscreen',
'converse-headline',
'converse-mam-views',
'converse-message-view',
'converse-minimize',
'converse-modal',
......
// Converse.js (A browser based XMPP chat client)
// https://conversejs.org
//
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Copyright (c) 2012-2019, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
// XEP-0059 Result Set Management
// XEP-0313 Message Archive Management
import "./converse-disco";
import "strophejs-plugin-rsm";
......@@ -107,7 +105,7 @@ function queryForArchivedMessages (_converse, options, callback, errback) {
converse.plugins.add('converse-mam', {
dependencies: ['converse-chatview', 'converse-muc', 'converse-muc-views'],
dependencies: ['converse-muc'],
overrides: {
// Overrides mentioned here will be picked up by converse.js's
......@@ -141,7 +139,6 @@ converse.plugins.add('converse-mam', {
return message;
},
getUpdatedMessageAttributes (message, stanza) {
const attrs = this.__super__.getUpdatedMessageAttributes.apply(this, arguments);
if (message && !message.get('is_archived')) {
......@@ -151,159 +148,6 @@ converse.plugins.add('converse-mam', {
}
return attrs;
}
},
ChatBoxView: {
render () {
const result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchNewestMessages () {
/* Fetches messages that might have been archived *after*
* the last archived message in our local cache.
*/
if (this.disable_mam) { return; }
const { _converse } = this.__super__,
most_recent_msg = u.getMostRecentMessage(this.model);
if (_.isNil(most_recent_msg)) {
this.fetchArchivedMessages();
} else {
const stanza_id = most_recent_msg.get(`stanza_id ${this.model.get('jid')}`);
if (stanza_id) {
this.fetchArchivedMessages({'after': stanza_id});
} else {
this.fetchArchivedMessages({'start': most_recent_msg.get('time')});
}
}
},
fetchArchivedMessagesIfNecessary () {
/* Check if archived messages should be fetched, and if so, do so. */
if (this.disable_mam || this.model.get('mam_initialized')) {
return;
}
const { _converse } = this.__super__;
_converse.api.disco.supports(Strophe.NS.MAM, _converse.bare_jid).then(
(result) => { // Success
if (result.length) {
this.fetchArchivedMessages();
}
this.model.save({'mam_initialized': true});
},
() => { // Error
_converse.log(
"Error or timeout while checking for MAM support",
Strophe.LogLevel.ERROR
);
}
).catch((msg) => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
fetchArchivedMessages (options) {
const { _converse } = this.__super__;
if (this.disable_mam) { return; }
const is_groupchat = this.model.get('type') === CHATROOMS_TYPE;
let mam_jid, message_handler;
if (is_groupchat) {
mam_jid = this.model.get('jid');
message_handler = this.model.onMessage.bind(this.model);
} else {
mam_jid = _converse.bare_jid;
message_handler = _converse.chatboxes.onMessage.bind(_converse.chatboxes)
}
_converse.api.disco.supports(Strophe.NS.MAM, mam_jid).then(
(results) => { // Success
if (!results.length) { return; }
this.addSpinner();
_converse.api.archive.query(
// TODO: only query from the last message we have
// in our history
_.extend({
'groupchat': is_groupchat,
'before': '', // Page backwards from the most recent message
'max': _converse.archived_messages_page_size,
'with': this.model.get('jid'),
}, options),
(messages) => { // Success
this.clearSpinner();
_.each(messages, message_handler);
},
e => { // Error
this.clearSpinner();
_converse.log(
"Error or timeout while trying to fetch "+
"archived messages", Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
}
);
},
() => { // Error
_converse.log(
"Error or timeout while checking for MAM support",
Strophe.LogLevel.ERROR
);
}
).catch((msg) => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
onScroll (ev) {
const { _converse } = this.__super__;
if (this.content.scrollTop === 0 && this.model.messages.length) {
const oldest_message = this.model.messages.at(0);
const by_jid = this.model.get('jid');
const stanza_id = oldest_message.get(`stanza_id ${by_jid}`);
if (stanza_id) {
this.fetchArchivedMessages({'before': stanza_id});
} else {
this.fetchArchivedMessages({
'end': oldest_message.get('time')
});
}
}
},
},
ChatRoomView: {
initialize () {
const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:mam_enabled', this.fetchArchivedMessagesIfNecessary, this);
this.model.on('change:connection_status', this.fetchArchivedMessagesIfNecessary, this);
},
renderChatArea () {
const result = this.__super__.renderChatArea.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchArchivedMessagesIfNecessary () {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED ||
!this.model.get('mam_enabled') ||
this.model.get('mam_initialized')) {
return;
}
this.fetchArchivedMessages();
this.model.save({'mam_initialized': true});
}
}
},
......@@ -364,7 +208,7 @@ converse.plugins.add('converse-mam', {
}
};
/* Event handlers */
/************************ BEGIN Event Handlers ************************/
_converse.on('serviceDiscovered', (feature) => {
const prefs = feature.get('preferences') || {};
if (feature.get('var') === Strophe.NS.MAM &&
......@@ -377,21 +221,11 @@ converse.plugins.add('converse-mam', {
}
});
_converse.on('addClientFeatures', () => {
_converse.api.disco.own.features.add(Strophe.NS.MAM);
});
_converse.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.MAM));
/************************ END Event Handlers ************************/
_converse.on('afterMessagesFetched', (chatboxview) => {
chatboxview.fetchNewestMessages();
});
_converse.on('reconnected', () => {
const private_chats = _converse.chatboxviews.filter(
(view) => _.at(view, 'model.attributes.type')[0] === 'chatbox'
);
_.each(private_chats, (view) => view.fetchNewestMessages())
});
/************************ BEGIN API ************************/
_.extend(_converse.api, {
/**
* The [XEP-0313](https://xmpp.org/extensions/xep-0313.html) Message Archive Management API
......@@ -570,5 +404,6 @@ converse.plugins.add('converse-mam', {
}
}
});
/************************ END API ************************/
}
});
......@@ -44116,12 +44116,10 @@ __webpack_require__.r(__webpack_exports__);
// Converse.js (A browser based XMPP chat client)
// https://conversejs.org
//
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Copyright (c) 2012-2019, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
// XEP-0059 Result Set Management
// XEP-0313 Message Archive Management
......@@ -44254,7 +44252,7 @@ function queryForArchivedMessages(_converse, options, callback, errback) {
}
_converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam', {
dependencies: ['converse-chatview', 'converse-muc', 'converse-muc-views'],
dependencies: ['converse-muc'],
overrides: {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
......@@ -44304,182 +44302,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam
return attrs;
}
},
ChatBoxView: {
render() {
const result = this.__super__.render.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchNewestMessages() {
/* Fetches messages that might have been archived *after*
* the last archived message in our local cache.
*/
if (this.disable_mam) {
return;
}
const _converse = this.__super__._converse,
most_recent_msg = u.getMostRecentMessage(this.model);
if (_.isNil(most_recent_msg)) {
this.fetchArchivedMessages();
} else {
const stanza_id = most_recent_msg.get(`stanza_id ${this.model.get('jid')}`);
if (stanza_id) {
this.fetchArchivedMessages({
'after': stanza_id
});
} else {
this.fetchArchivedMessages({
'start': most_recent_msg.get('time')
});
}
}
},
fetchArchivedMessagesIfNecessary() {
/* Check if archived messages should be fetched, and if so, do so. */
if (this.disable_mam || this.model.get('mam_initialized')) {
return;
}
const _converse = this.__super__._converse;
_converse.api.disco.supports(Strophe.NS.MAM, _converse.bare_jid).then(result => {
// Success
if (result.length) {
this.fetchArchivedMessages();
}
this.model.save({
'mam_initialized': true
});
}, () => {
// Error
_converse.log("Error or timeout while checking for MAM support", Strophe.LogLevel.ERROR);
}).catch(msg => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
fetchArchivedMessages(options) {
const _converse = this.__super__._converse;
if (this.disable_mam) {
return;
}
const is_groupchat = this.model.get('type') === CHATROOMS_TYPE;
let mam_jid, message_handler;
if (is_groupchat) {
mam_jid = this.model.get('jid');
message_handler = this.model.onMessage.bind(this.model);
} else {
mam_jid = _converse.bare_jid;
message_handler = _converse.chatboxes.onMessage.bind(_converse.chatboxes);
}
_converse.api.disco.supports(Strophe.NS.MAM, mam_jid).then(results => {
// Success
if (!results.length) {
return;
}
this.addSpinner();
_converse.api.archive.query( // TODO: only query from the last message we have
// in our history
_.extend({
'groupchat': is_groupchat,
'before': '',
// Page backwards from the most recent message
'max': _converse.archived_messages_page_size,
'with': this.model.get('jid')
}, options), messages => {
// Success
this.clearSpinner();
_.each(messages, message_handler);
}, e => {
// Error
this.clearSpinner();
_converse.log("Error or timeout while trying to fetch " + "archived messages", Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
});
}, () => {
// Error
_converse.log("Error or timeout while checking for MAM support", Strophe.LogLevel.ERROR);
}).catch(msg => {
this.clearSpinner();
_converse.log(msg, Strophe.LogLevel.FATAL);
});
},
onScroll(ev) {
const _converse = this.__super__._converse;
if (this.content.scrollTop === 0 && this.model.messages.length) {
const oldest_message = this.model.messages.at(0);
const by_jid = this.model.get('jid');
const stanza_id = oldest_message.get(`stanza_id ${by_jid}`);
if (stanza_id) {
this.fetchArchivedMessages({
'before': stanza_id
});
} else {
this.fetchArchivedMessages({
'end': oldest_message.get('time')
});
}
}
}
},
ChatRoomView: {
initialize() {
const _converse = this.__super__._converse;
this.__super__.initialize.apply(this, arguments);
this.model.on('change:mam_enabled', this.fetchArchivedMessagesIfNecessary, this);
this.model.on('change:connection_status', this.fetchArchivedMessagesIfNecessary, this);
},
renderChatArea() {
const result = this.__super__.renderChatArea.apply(this, arguments);
if (!this.disable_mam) {
this.content.addEventListener('scroll', _.debounce(this.onScroll.bind(this), 100));
}
return result;
},
fetchArchivedMessagesIfNecessary() {
if (this.model.get('connection_status') !== _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].ROOMSTATUS.ENTERED || !this.model.get('mam_enabled') || this.model.get('mam_initialized')) {
return;
}
this.fetchArchivedMessages();
this.model.save({
'mam_initialized': true
});
}
}
},
......@@ -44547,7 +44369,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam
});
}
};
/* Event handlers */
/************************ BEGIN Event Handlers ************************/
_converse.on('serviceDiscovered', feature => {
......@@ -44564,19 +44386,11 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam
}
});
_converse.on('addClientFeatures', () => {
_converse.api.disco.own.features.add(Strophe.NS.MAM);
});
_converse.on('afterMessagesFetched', chatboxview => {
chatboxview.fetchNewestMessages();
});
_converse.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.MAM));
/************************ END Event Handlers ************************/
_converse.on('reconnected', () => {
const private_chats = _converse.chatboxviews.filter(view => _.at(view, 'model.attributes.type')[0] === 'chatbox');
/************************ BEGIN API ************************/
_.each(private_chats, view => view.fetchNewestMessages());
});
_.extend(_converse.api, {
/**
......@@ -44757,6 +44571,8 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam
}
}
});
/************************ END API ************************/
}
});
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