Skip to content

Commit

Permalink
Add an exports attribute on the _converse object.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcbrand committed Nov 3, 2023
1 parent e664aa3 commit b8b7429
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 38 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

- Remove the old `_converse.BootstrapModal` in favor of `_converse.BaseModal` which is a web component.
- The connection is no longer available on the `_converse` object. Instead, use `api.connection.get()`.
- Add a new `exports` attribute on the `_converse` object which is meant for
providing access for 3rd party plugins to code (e.g. classes) from
converse.js. Some classes that were on the `_converse` object, like
`CustomElement` are not on `_converse.exports`.

## 10.1.6 (2023-08-31)

Expand Down
5 changes: 4 additions & 1 deletion src/headless/plugins/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ converse.plugins.add('converse-chat', {
'send_chat_state_notifications': true,
});

Object.assign(_converse, { ChatBox, Message, Messages, handleMessageStanza });
const exports = { ChatBox, Message, Messages, handleMessageStanza };
Object.assign(_converse, exports); // TODO: DEPRECATED
Object.assign(_converse.exports, exports);

Object.assign(api, chat_api);

api.chatboxes.registry.add(PRIVATE_CHAT_TYPE, ChatBox);
Expand Down
13 changes: 5 additions & 8 deletions src/headless/plugins/chat/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -887,8 +887,8 @@ class ChatBox extends ModelWithContact {
* will be editable. Otherwise no messages will be editable.
* @method ChatBox#setEditable
* @memberOf ChatBox
* @param { Object } attrs An object containing message attributes.
* @param { String } send_time - time when the message was sent
* @param {Object} attrs An object containing message attributes.
* @param {String} send_time - time when the message was sent
*/
setEditable (attrs, send_time) {
if (attrs.is_headline || isEmptyMessage(attrs) || attrs.sender !== 'me') {
Expand All @@ -907,10 +907,8 @@ class ChatBox extends ModelWithContact {
* Queue the creation of a message, to make sure that we don't run
* into a race condition whereby we're creating a new message
* before the collection has been fetched.
* @async
* @private
* @method ChatBox#createMessage
* @param { Object } attrs
* @param {Object} attrs
*/
async createMessage (attrs, options) {
attrs.time = attrs.time || (new Date()).toISOString();
Expand All @@ -920,11 +918,10 @@ class ChatBox extends ModelWithContact {

/**
* Responsible for sending off a text message inside an ongoing chat conversation.
* @private
* @method ChatBox#sendMessage
* @memberOf ChatBox
* @param { Object } [attrs] - A map of attributes to be saved on the message
* @returns { Promise<Message> }
* @param {Object} [attrs] - A map of attributes to be saved on the message
* @returns {Promise<Message>}
* @example
* const chat = api.chats.get('[email protected]');
* chat.sendMessage({'body': 'hello world'});
Expand Down
6 changes: 5 additions & 1 deletion src/headless/plugins/muc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,16 @@ converse.plugins.add('converse-muc', {
routeToRoom();
addEventListener('hashchange', routeToRoom);

// TODO: DEPRECATED
_converse.ChatRoom = MUC;
_converse.ChatRoomMessage = MUCMessage;
_converse.ChatRoomOccupants = ChatRoomOccupants;
_converse.ChatRoomOccupant = ChatRoomOccupant;

api.chatboxes.registry.add(CHATROOMS_TYPE, MUC);
const exports = { MUC, MUCMessage, ChatRoomOccupants, ChatRoomOccupant };
Object.assign(_converse.exports, exports);

/** @type {module:shared-api.APIEndpoint} */(api.chatboxes.registry).add(CHATROOMS_TYPE, MUC);

Object.assign(_converse, {
getDefaultMUCNickname,
Expand Down
34 changes: 17 additions & 17 deletions src/headless/plugins/muc/muc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { getUniqueId, safeSave } from '../../utils/index.js';
import { isUniView } from '../../utils/session.js';
import { parseMUCMessage, parseMUCPresence } from './parsers.js';
import { sendMarker } from '../../shared/actions.js';
import { shouldCreateGroupchatMessage } from './utils.js';
import { shouldCreateGroupchatMessage, isInfoVisible } from './utils.js';

const { u } = converse.env;

Expand Down Expand Up @@ -316,7 +316,7 @@ class MUC extends ChatBox {

onOccupantAdded (occupant) {
if (
_converse.isInfoVisible(converse.MUC_TRAFFIC_STATES.ENTERED) &&
isInfoVisible(converse.MUC_TRAFFIC_STATES.ENTERED) &&
this.session.get('connection_status') === ROOMSTATUS.ENTERED &&
occupant.get('show') === 'online'
) {
Expand All @@ -326,7 +326,7 @@ class MUC extends ChatBox {

onOccupantRemoved (occupant) {
if (
_converse.isInfoVisible(converse.MUC_TRAFFIC_STATES.EXITED) &&
isInfoVisible(converse.MUC_TRAFFIC_STATES.EXITED) &&
this.isEntered() &&
occupant.get('show') === 'online'
) {
Expand All @@ -338,9 +338,9 @@ class MUC extends ChatBox {
if (occupant.get('states').includes('303')) {
return;
}
if (occupant.get('show') === 'offline' && _converse.isInfoVisible(converse.MUC_TRAFFIC_STATES.EXITED)) {
if (occupant.get('show') === 'offline' && isInfoVisible(converse.MUC_TRAFFIC_STATES.EXITED)) {
this.updateNotifications(occupant.get('nick'), converse.MUC_TRAFFIC_STATES.EXITED);
} else if (occupant.get('show') === 'online' && _converse.isInfoVisible(converse.MUC_TRAFFIC_STATES.ENTERED)) {
} else if (occupant.get('show') === 'online' && isInfoVisible(converse.MUC_TRAFFIC_STATES.ENTERED)) {
this.updateNotifications(occupant.get('nick'), converse.MUC_TRAFFIC_STATES.ENTERED);
}
}
Expand Down Expand Up @@ -2390,19 +2390,19 @@ class MUC extends ChatBox {
}

const current_affiliation = occupant.get('affiliation');
if (previous_affiliation === 'admin' && _converse.isInfoVisible(converse.AFFILIATION_CHANGES.EXADMIN)) {
if (previous_affiliation === 'admin' && isInfoVisible(converse.AFFILIATION_CHANGES.EXADMIN)) {
this.createMessage({
'type': 'info',
'message': __('%1$s is no longer an admin of this groupchat', occupant.get('nick'))
});
} else if (previous_affiliation === 'owner' && _converse.isInfoVisible(converse.AFFILIATION_CHANGES.EXOWNER)) {
} else if (previous_affiliation === 'owner' && isInfoVisible(converse.AFFILIATION_CHANGES.EXOWNER)) {
this.createMessage({
'type': 'info',
'message': __('%1$s is no longer an owner of this groupchat', occupant.get('nick'))
});
} else if (
previous_affiliation === 'outcast' &&
_converse.isInfoVisible(converse.AFFILIATION_CHANGES.EXOUTCAST)
isInfoVisible(converse.AFFILIATION_CHANGES.EXOUTCAST)
) {
this.createMessage({
'type': 'info',
Expand All @@ -2413,22 +2413,22 @@ class MUC extends ChatBox {
if (
current_affiliation === 'none' &&
previous_affiliation === 'member' &&
_converse.isInfoVisible(converse.AFFILIATION_CHANGES.EXMEMBER)
isInfoVisible(converse.AFFILIATION_CHANGES.EXMEMBER)
) {
this.createMessage({
'type': 'info',
'message': __('%1$s is no longer a member of this groupchat', occupant.get('nick'))
});
}

if (current_affiliation === 'member' && _converse.isInfoVisible(converse.AFFILIATION_CHANGES.MEMBER)) {
if (current_affiliation === 'member' && isInfoVisible(converse.AFFILIATION_CHANGES.MEMBER)) {
this.createMessage({
'type': 'info',
'message': __('%1$s is now a member of this groupchat', occupant.get('nick'))
});
} else if (
(current_affiliation === 'admin' && _converse.isInfoVisible(converse.AFFILIATION_CHANGES.ADMIN)) ||
(current_affiliation == 'owner' && _converse.isInfoVisible(converse.AFFILIATION_CHANGES.OWNER))
(current_affiliation === 'admin' && isInfoVisible(converse.AFFILIATION_CHANGES.ADMIN)) ||
(current_affiliation == 'owner' && isInfoVisible(converse.AFFILIATION_CHANGES.OWNER))
) {
// For example: AppleJack is now an (admin|owner) of this groupchat
this.createMessage({
Expand All @@ -2444,17 +2444,17 @@ class MUC extends ChatBox {
return;
}
const previous_role = occupant._previousAttributes.role;
if (previous_role === 'moderator' && _converse.isInfoVisible(converse.MUC_ROLE_CHANGES.DEOP)) {
if (previous_role === 'moderator' && isInfoVisible(converse.MUC_ROLE_CHANGES.DEOP)) {
this.updateNotifications(occupant.get('nick'), converse.MUC_ROLE_CHANGES.DEOP);
} else if (previous_role === 'visitor' && _converse.isInfoVisible(converse.MUC_ROLE_CHANGES.VOICE)) {
} else if (previous_role === 'visitor' && isInfoVisible(converse.MUC_ROLE_CHANGES.VOICE)) {
this.updateNotifications(occupant.get('nick'), converse.MUC_ROLE_CHANGES.VOICE);
}
if (occupant.get('role') === 'visitor' && _converse.isInfoVisible(converse.MUC_ROLE_CHANGES.MUTE)) {
if (occupant.get('role') === 'visitor' && isInfoVisible(converse.MUC_ROLE_CHANGES.MUTE)) {
this.updateNotifications(occupant.get('nick'), converse.MUC_ROLE_CHANGES.MUTE);
} else if (occupant.get('role') === 'moderator') {
if (
!['owner', 'admin'].includes(occupant.get('affiliation')) &&
_converse.isInfoVisible(converse.MUC_ROLE_CHANGES.OP)
isInfoVisible(converse.MUC_ROLE_CHANGES.OP)
) {
// Oly show this message if the user isn't already
// an admin or owner, otherwise this isn't new information.
Expand All @@ -2474,7 +2474,7 @@ class MUC extends ChatBox {
createInfoMessage (code, stanza, is_self) {
const __ = _converse.__;
const data = { 'type': 'info', 'is_ephemeral': true };
if (!_converse.isInfoVisible(code)) {
if (!isInfoVisible(code)) {
return;
}
if (code === '110' || (code === '100' && !is_self)) {
Expand Down
10 changes: 9 additions & 1 deletion src/headless/shared/_converse.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,17 @@ class ConversePrivateGlobal extends EventEmitter(Object) {
this.TIMEOUTS = {
PAUSED: 10000,
INACTIVE: 90000
}
};

this.chatboxes = null;

/**
* Namespace for storing code that might be useful to 3rd party
* plugins. We want to make it possible for 3rd party plugins to have
* access to code (e.g. classes) from converse.js without having to add
* converse.js as a dependency.
*/
this.exports = /** @type { Record<string, Object> } */{};
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/headless/shared/api/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* @typedef {import('../_converse.js').default} _converse
* @typedef {module:shared-api.APIEndpoint} APIEndpoint
*/
import connection_api from '../connection/api.js';
import events_api from './events.js';
import promise_api from './promise.js';
Expand All @@ -17,7 +21,10 @@ import { settings_api } from '../settings/api.js';
*
* @memberOf _converse
* @namespace api
* @property {Object} disco
* @typedef {Record<string, Function>} module:shared-api.APIEndpoint
* @typedef {Record<string, APIEndpoint|Function>} APINamespace
* @typedef {Record<string, APINamespace|APIEndpoint|Function>} API
* @type {API}
*/
const api = {
connection: connection_api,
Expand Down
3 changes: 1 addition & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ import "./plugins/dragresize/index.js"; // Allows chat boxes to be resized b
import "./plugins/fullscreen/index.js";
/* END: Removable components */


_converse.CustomElement = CustomElement;
_converse.exports.CustomElement = CustomElement;

const initialize = converse.initialize;

Expand Down
15 changes: 8 additions & 7 deletions src/utils/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import u from '../headless/utils/index.js';
import { converse, log } from '@converse/headless';
import { getURI, isAudioURL, isImageURL, isVideoURL } from '@converse/headless/utils/url.js';
import { render } from 'lit';
import { queryChildren } from '@converse/headless/utils/html.js';

const { sizzle, Strophe } = converse.env;

Expand Down Expand Up @@ -527,15 +528,15 @@ u.fadeIn = function (el, callback) {
* Takes an XML field in XMPP XForm (XEP-004: Data Forms) format returns a
* [TemplateResult](https://lit.polymer-project.org/api/classes/_lit_html_.templateresult.html).
* @method u#xForm2TemplateResult
* @param { Element } field - the field to convert
* @param { Element } stanza - the containing stanza
* @param { Object } options
* @returns { TemplateResult }
* @param {HTMLElement} field - the field to convert
* @param {Element} stanza - the containing stanza
* @param {Object} options
* @returns {import('lit').TemplateResult}
*/
u.xForm2TemplateResult = function (field, stanza, options={}) {
export function xForm2TemplateResult (field, stanza, options={}) {
if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') {
const values = u.queryChildren(field, 'value').map(el => el?.textContent);
const options = u.queryChildren(field, 'option').map(option => {
const values = queryChildren(field, 'value').map(el => el?.textContent);
const options = queryChildren(field, 'option').map(/** @type {HTMLElement} */(option) => {
const value = option.querySelector('value')?.textContent;
return {
'value': value,
Expand Down

0 comments on commit b8b7429

Please sign in to comment.