xmpp.chapril.org-conversejs/src/headless/converse-chatboxes.js

185 lines
6.8 KiB
JavaScript
Raw Normal View History

/**
* @module converse-chatboxes
2020-01-26 16:21:20 +01:00
* @copyright 2020, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import "./converse-emoji";
2019-09-19 16:54:55 +02:00
import { Collection } from "skeletor.js/src/collection";
2020-04-23 13:22:31 +02:00
import { converse } from "./converse-core";
import { isString } from "lodash";
import log from "./log";
2018-10-23 03:41:38 +02:00
const { Strophe } = converse.env;
2018-10-23 03:41:38 +02:00
Strophe.addNamespace('MESSAGE_CORRECT', 'urn:xmpp:message-correct:0');
Strophe.addNamespace('RECEIPTS', 'urn:xmpp:receipts');
2018-10-23 03:41:38 +02:00
Strophe.addNamespace('REFERENCE', 'urn:xmpp:reference:0');
Strophe.addNamespace('MARKERS', 'urn:xmpp:chat-markers:0');
2018-10-23 03:41:38 +02:00
converse.plugins.add('converse-chatboxes', {
dependencies: ["converse-emoji", "converse-roster", "converse-vcard"],
2018-10-23 03:41:38 +02:00
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const { _converse } = this;
const { api } = _converse;
2018-10-23 03:41:38 +02:00
api.promises.add([
2018-10-23 03:41:38 +02:00
'chatBoxesFetched',
2018-12-17 11:42:43 +01:00
'chatBoxesInitialized',
2018-10-23 03:41:38 +02:00
'privateChatsAutoJoined'
]);
let msg_counter = 0;
_converse.incrementMsgCounter = function () {
msg_counter += 1;
const title = document.title;
if (!title) {
return;
}
if (title.search(/^Messages \(\d+\) /) === -1) {
document.title = `Messages (${msg_counter}) ${title}`;
} else {
document.title = title.replace(/^Messages \(\d+\) /, `Messages (${msg_counter}) `);
}
};
_converse.clearMsgCounter = function () {
msg_counter = 0;
const title = document.title;
if (!title) {
return;
}
if (title.search(/^Messages \(\d+\) /) !== -1) {
document.title = title.replace(/^Messages \(\d+\) /, "");
}
};
2019-09-19 16:54:55 +02:00
_converse.ChatBoxes = Collection.extend({
2018-10-23 03:41:38 +02:00
comparator: 'time_opened',
2018-10-23 03:41:38 +02:00
model (attrs, options) {
return new _converse.ChatBox(attrs, options);
},
2018-10-23 03:41:38 +02:00
onChatBoxesFetched (collection) {
collection.filter(c => !c.isValid()).forEach(c => c.destroy());
2019-03-29 15:47:23 +01:00
/**
* Triggered when a message stanza is been received and processed.
* @event _converse#chatBoxesFetched
2019-03-29 15:47:23 +01:00
* @type { object }
* @property { _converse.ChatBox | _converse.ChatRoom } chatbox
* @property { XMLElement } stanza
* @example _converse.api.listen.on('message', obj => { ... });
* @example _converse.api.waitUntil('chatBoxesFetched').then(() => { ... });
*/
api.trigger('chatBoxesFetched');
2018-10-23 03:41:38 +02:00
},
onConnected (reconnecting) {
if (reconnecting) { return; }
this.browserStorage = _converse.createStore(`converse.chatboxes-${_converse.bare_jid}`);
2018-10-23 03:41:38 +02:00
this.fetch({
'add': true,
'success': c => this.onChatBoxesFetched(c)
2018-10-23 03:41:38 +02:00
});
}
2018-10-23 03:41:38 +02:00
});
2019-09-19 16:54:55 +02:00
async function createChatBox (jid, attrs, Model) {
jid = Strophe.getBareJidFromJid(jid.toLowerCase());
Object.assign(attrs, {'jid': jid, 'id': jid});
let chatbox;
try {
2019-09-19 16:54:55 +02:00
chatbox = new Model(attrs, {'collection': _converse.chatboxes});
} catch (e) {
log.error(e);
return null;
}
await chatbox.initialized;
if (!chatbox.isValid()) {
chatbox.destroy();
return null;
}
_converse.chatboxes.add(chatbox);
await chatbox.messages.fetched;
return chatbox;
2018-10-23 03:41:38 +02:00
}
2018-10-23 03:41:38 +02:00
/************************ BEGIN Event Handlers ************************/
api.listen.on('addClientFeatures', () => {
api.disco.own.features.add(Strophe.NS.MESSAGE_CORRECT);
api.disco.own.features.add(Strophe.NS.HTTPUPLOAD);
api.disco.own.features.add(Strophe.NS.OUTOFBAND);
2018-10-23 03:41:38 +02:00
});
api.listen.on('pluginsInitialized', () => {
2019-03-29 21:36:49 +01:00
_converse.chatboxes = new _converse.ChatBoxes();
/**
* Triggered once the _converse.ChatBoxes collection has been initialized.
* @event _converse#chatBoxesInitialized
* @example _converse.api.listen.on('chatBoxesInitialized', () => { ... });
* @example _converse.api.waitUntil('chatBoxesInitialized').then(() => { ... });
*/
api.trigger('chatBoxesInitialized');
2019-03-29 21:36:49 +01:00
});
api.listen.on('presencesInitialized', (reconnecting) => _converse.chatboxes.onConnected(reconnecting));
api.listen.on('reconnected', () => _converse.chatboxes.forEach(m => m.onReconnection()));
api.listen.on('windowStateChanged', d => (d.state === 'visible') && _converse.clearMsgCounter());
2018-10-23 03:41:38 +02:00
/************************ END Event Handlers ************************/
/************************ BEGIN API ************************/
Object.assign(api, {
2018-10-23 03:41:38 +02:00
/**
* The "chatboxes" namespace.
2018-10-23 03:41:38 +02:00
*
* @namespace api.chatboxes
* @memberOf api
2018-10-23 03:41:38 +02:00
*/
chatboxes: {
/**
* @method api.chats.create
* @param { String|String[] } jids - A JID or array of JIDs
* @param { Object } [attrs] An object containing configuration attributes
2019-09-19 16:54:55 +02:00
* @param { Model } model - The type of chatbox that should be created
*/
async create (jids=[], attrs={}, model) {
await api.waitUntil('chatBoxesFetched');
if (isString(jids)) {
return createChatBox(jids, attrs, model);
} else {
return Promise.all(jids.map(jid => createChatBox(jid, attrs, model)));
}
2018-10-23 03:41:38 +02:00
},
/**
* @method api.chats.get
* @param { String|String[] } jids - A JID or array of JIDs
2018-10-23 03:41:38 +02:00
*/
async get (jids) {
await api.waitUntil('chatBoxesFetched');
2019-07-29 10:19:05 +02:00
if (jids === undefined) {
return _converse.chatboxes.models;
} else if (isString(jids)) {
return _converse.chatboxes.get(jids.toLowerCase());
} else {
jids = jids.map(j => j.toLowerCase());
return _converse.chatboxes.models.filter(m => jids.includes(m.get('jid')));
}
}
2018-10-23 03:41:38 +02:00
}
});
/************************ END API ************************/
}
});