Breaking change: stop setting config variables on the _converse object

This commit is contained in:
JC Brand 2021-09-15 15:37:00 +02:00
parent 864e8910c4
commit 05dcb4e8d7
29 changed files with 72 additions and 48 deletions

View File

@ -14,6 +14,12 @@ Three config settings have been obsoleted:
- show_images_inline
### Breaking Changes
Configuration settings are no longer available on the `_converse` object.
Instead, use `api.settings.get` and `api.settings.set`.
## 8.0.2 (Unreleased)
- #2640: Add `beforeFetchLoginCredentials` hook

View File

@ -3,7 +3,7 @@ const { Strophe } = converse.env;
export async function checkBookmarksSupport () {
const identity = await api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid);
if (_converse.allow_public_bookmarks) {
if (api.settings.get('allow_public_bookmarks')) {
return !!identity;
} else {
return api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', _converse.bare_jid);

View File

@ -22,7 +22,7 @@ const XMPPStatus = Model.extend({
},
getNickname () {
return _converse.nickname;
return api.settings.get('nickname');
},
getFullname () {

View File

@ -21,7 +21,6 @@ export function initAppSettings (settings) {
app_settings = {};
// Allow only whitelisted settings to be overwritten via converse.initialize
const allowed_settings = pick(settings, Object.keys(DEFAULT_SETTINGS));
assignIn(_converse, DEFAULT_SETTINGS, allowed_settings); // FIXME: remove
assignIn(app_settings, DEFAULT_SETTINGS, allowed_settings);
}
@ -43,17 +42,14 @@ export function extendAppSettings (settings) {
const allowed_site_settings = pick(init_settings, allowed_keys);
const updated_settings = assignIn(pick(settings, allowed_keys), allowed_site_settings);
u.merge(app_settings, updated_settings);
u.merge(_converse, updated_settings); // FIXME: remove
}
export function updateAppSettings (key, val) {
const o = {};
if (isObject(key)) {
assignIn(_converse, pick(key, Object.keys(DEFAULT_SETTINGS))); // FIXME: remove
assignIn(app_settings, pick(key, Object.keys(DEFAULT_SETTINGS)));
} else if (typeof key === 'string') {
o[key] = val;
assignIn(_converse, pick(o, Object.keys(DEFAULT_SETTINGS))); // FIXME: remove
assignIn(app_settings, pick(o, Object.keys(DEFAULT_SETTINGS)));
}
}

View File

@ -7,7 +7,8 @@ describe("Converse", function() {
describe("Authentication", function () {
it("needs either a bosh_service_url a websocket_url or both", mock.initConverse(async (_converse) => {
const url = _converse.bosh_service_url;
const { api } = _converse;
const url = api.settings.get('bosh_service_url');
const connection = _converse.connection;
_converse.api.settings.set('bosh_service_url', undefined);
delete _converse.connection;
@ -53,6 +54,8 @@ describe("Converse", function() {
it("happens when the client is idle for long enough",
mock.initConverse(['initialized'], {}, async (_converse) => {
const { api } = _converse;
let i = 0;
// Usually initialized by registerIntervalHandler
_converse.idle_seconds = 0;
@ -66,7 +69,7 @@ describe("Converse", function() {
}
expect(_converse.auto_changed_status).toBe(true);
while (i <= _converse.auto_xa) {
while (i <= api.settings.get('auto_xa')) {
expect(await _converse.api.user.status.get()).toBe('away');
_converse.onEverySecond();
i++;
@ -86,7 +89,7 @@ describe("Converse", function() {
i++;
}
expect(_converse.auto_changed_status).toBe(true);
while (i <= _converse.auto_xa) {
while (i <= api.settings.get('auto_xa')) {
expect(await _converse.api.user.status.get()).toBe('away');
_converse.onEverySecond();
i++;
@ -107,7 +110,7 @@ describe("Converse", function() {
}
expect(await _converse.api.user.status.get()).toBe('dnd');
expect(_converse.auto_changed_status).toBe(false);
while (i <= _converse.auto_xa) {
while (i <= api.settings.get('auto_xa')) {
expect(await _converse.api.user.status.get()).toBe('dnd');
_converse.onEverySecond();
i++;

View File

@ -1,5 +1,6 @@
import { html } from "lit";
import { __ } from 'i18n';
import { api } from '@converse/headless/core.js';
import { html } from "lit";
import { modal_header_close_button } from "plugins/modal/templates/buttons.js"
@ -24,7 +25,7 @@ export default (o) => {
<label class="clearfix" for="jid">${i18n_xmpp_address}:</label>
<div class="suggestion-box suggestion-box__jid">
<ul class="suggestion-box__results suggestion-box__results--above" hidden=""></ul>
<input type="text" name="jid" ?required=${(!o._converse.xhr_user_search_url)}
<input type="text" name="jid" ?required=${(!api.settings.get('xhr_user_search_url'))}
value="${o.jid || ''}"
class="form-control suggestion-box__input"
placeholder="${i18n_contact_placeholder}"/>

View File

@ -135,6 +135,7 @@ describe("A chat room", function () {
['chatBoxesFetched'], {}, async function (_converse) {
const { u } = converse.env;
const { api } = _converse;
await mock.waitForRoster(_converse, 'current', 0);
await mock.waitUntilDiscoConfirmed(
_converse, _converse.bare_jid,
@ -162,7 +163,7 @@ describe("A chat room", function () {
expect(!!_converse.chatboxviews.get(jid)).toBe(true);
// Check that we don't auto-join if muc_respect_autojoin is false
_converse.muc_respect_autojoin = false;
api.settings.set('muc_respect_autojoin', false);
jid = 'balcony@conference.shakespeare.lit';
_converse.bookmarks.create({
'jid': jid,

View File

@ -6,7 +6,7 @@ import { __ } from 'i18n';
export function getHeadingButtons (view, buttons) {
if (_converse.allow_bookmarks && view.model.get('type') === _converse.CHATROOMS_TYPE) {
if (api.settings.get('allow_bookmarks') && view.model.get('type') === _converse.CHATROOMS_TYPE) {
const bookmarked = view.model.get('bookmarked');
const data = {
'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'),

View File

@ -298,6 +298,7 @@ describe("Chatboxes", function () {
it("can contain a button for starting a call",
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
const { api } = _converse;
await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse);
@ -306,7 +307,10 @@ describe("Chatboxes", function () {
spyOn(_converse.api, "trigger").and.callThrough();
// First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons"
_converse.visible_toolbar_buttons.call = false;
let buttons = api.settings.get('visible_toolbar_buttons');
api.settings.set('visible_toolbar_buttons', Object.assign({}, buttons, {'call': false}));
await mock.openChatBoxFor(_converse, contact_jid);
let view = _converse.chatboxviews.get(contact_jid);
toolbar = view.querySelector('.chat-toolbar');
@ -315,7 +319,9 @@ describe("Chatboxes", function () {
view.close();
// Now check that it's shown if enabled and that it emits
// callButtonClicked
_converse.visible_toolbar_buttons.call = true; // enable the button
buttons = api.settings.get('visible_toolbar_buttons');
api.settings.set('visible_toolbar_buttons', Object.assign({}, buttons, {'call': true}));
await mock.openChatBoxFor(_converse, contact_jid);
view = _converse.chatboxviews.get(contact_jid);
toolbar = view.querySelector('.chat-toolbar');

View File

@ -78,13 +78,14 @@ describe("A Chat Message", function () {
it("can be received out of order, and will still be displayed in the right order",
mock.initConverse([], {}, async function (_converse) {
const { api } = _converse;
await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length)
_converse.filter_by_resource = true;
api.settings.set('filter_by_resource', true);
let msg = $msg({
'xmlns': 'jabber:client',
@ -629,6 +630,8 @@ describe("A Chat Message", function () {
[], {'debounced_content_rendering': false},
async function (_converse) {
const { api } = _converse;
await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse);
@ -638,7 +641,7 @@ describe("A Chat Message", function () {
const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
_converse.filter_by_resource = true;
api.settings.set('filter_by_resource', true);
jasmine.clock().install();
jasmine.clock().mockDate(base_time);

View File

@ -45,7 +45,7 @@ const register_link = () => {
}
const show_register_link = () => {
return _converse.allow_registration &&
return api.settings.get('allow_registration') &&
!api.settings.get("auto_login") &&
_converse.pluggable.plugins['converse-register'].enabled(_converse);
}

View File

@ -144,11 +144,10 @@ describe("A headlines box", function () {
it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
mock.initConverse(
['chatBoxesFetched'], {}, async function (_converse) {
['chatBoxesFetched'], {'allow_non_roster_messaging': false}, async function (_converse) {
await mock.waitForRoster(_converse, 'current', 0);
const { $msg } = converse.env;
_converse.allow_non_roster_messaging = false;
const stanza = $msg({
'type': 'headline',
'from': 'andre5114@jabber.snc.ru/Spark',

View File

@ -305,7 +305,7 @@ describe("Message Archive Management", function () {
view.model.afterMessagesFetched(view.model.messages);
view.model.messages.fetched.resolve();
const affs = _converse.muc_fetch_members;
const affs = api.settings.get('muc_fetch_members');
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
await mock.returnMemberLists(_converse, muc_jid, [], all_affiliations);

View File

@ -1,7 +1,7 @@
import tpl_muc_chatarea from './templates/muc-chatarea.js';
import { CustomElement } from 'shared/components/element.js';
import { __ } from 'i18n';
import { _converse, api, converse } from '@converse/headless/core';
import { api, converse } from '@converse/headless/core';
const { u } = converse.env;
@ -41,7 +41,7 @@ export default class MUCChatArea extends CustomElement {
'jid': this.jid,
'model': this.model,
'onMousedown': ev => this.onMousedown(ev),
'show_send_button': _converse.show_send_button,
'show_send_button': api.settings.get('show_send_button'),
'shouldShowSidebar': () => this.shouldShowSidebar(),
'type': this.type,
});

View File

@ -84,7 +84,7 @@ export default BootstrapModal.extend({
checkRoomidPolicy () {
if (api.settings.get('muc_roomid_policy') && api.settings.get('muc_domain')) {
let jid = this.el.querySelector('.roomjid-input').value;
if (converse.locked_muc_domain || !u.isValidJID(jid)) {
if (api.settings.get('locked_muc_domain') || !u.isValidJID(jid)) {
jid = `${Strophe.escapeNode(jid)}@${api.settings.get('muc_domain')}`;
}
const roomid = Strophe.getNodeFromJid(jid);

View File

@ -1,5 +1,6 @@
import DOMPurify from 'dompurify';
import { __ } from 'i18n';
import { api } from '@converse/headless/core.js';
import { html } from "lit";
import { modal_header_close_button } from "plugins/modal/templates/buttons.js"
import { unsafeHTML } from "lit/directives/unsafe-html.js";
@ -36,7 +37,7 @@ export default (o) => {
<input type="text" required="required" name="chatroom" class="form-control roomjid-input" placeholder="${o.chatroom_placeholder}"/>
</div>
${ o.muc_roomid_policy_hint ? html`<div class="form-group">${unsafeHTML(DOMPurify.sanitize(o.muc_roomid_policy_hint, {'ALLOWED_TAGS': ['b', 'br', 'em']}))}</div>` : '' }
${ !o._converse.locked_muc_nickname ? nickname_input(o) : '' }
${ !api.settings.get('locked_muc_nickname') ? nickname_input(o) : '' }
<input type="submit" class="btn btn-primary" name="join" value="${i18n_join || ''}" ?disabled=${o.muc_roomid_policy_error_msg}>
</form>
</div>

View File

@ -1,7 +1,7 @@
import 'shared/components/dropdown.js';
import 'shared/components/rich-text.js';
import { __ } from 'i18n';
import { _converse } from "@converse/headless/core";
import { _converse, api } from "@converse/headless/core";
import { html } from "lit";
import { until } from 'lit/directives/until.js';
@ -15,7 +15,7 @@ export default (o) => {
return html`
<div class="chatbox-title ${ show_subject ? '' : "chatbox-title--no-desc"}">
${ (!_converse.api.settings.get("singleton")) ? html`<converse-controlbox-navback jid="${o.jid}"></converse-controlbox-navback>` : '' }
<div class="chatbox-title__text" title="${ (_converse.locked_muc_domain !== 'hidden') ? o.jid : '' }">${ o.title }
<div class="chatbox-title__text" title="${ (api.settings.get('locked_muc_domain') !== 'hidden') ? o.jid : '' }">${ o.title }
${ (o.bookmarked) ? html`<i class="fa fa-bookmark chatbox-title__text--bookmarked" title="${i18n_bookmarked}"></i>` : '' }
</div>
<div class="chatbox-title__buttons row no-gutters">

View File

@ -48,7 +48,7 @@ describe("The <converse-muc> component", function () {
await muc_creation_promise;
const model = _converse.chatboxes.get(muc_jid);
await u.waitUntil(() => (model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
const affs = _converse.muc_fetch_members;
const affs = api.settings.get('muc_fetch_members');
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
await mock.returnMemberLists(_converse, muc_jid, [], all_affiliations);
await model.messages.fetched;

View File

@ -99,6 +99,8 @@ describe("Groupchats", function () {
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
const { api } = _converse;
// Mock 'getDiscoInfo', otherwise the room won't be
// displayed as it waits first for the features to be returned
// (when it's a new room being created).
@ -146,7 +148,7 @@ describe("Groupchats", function () {
await u.waitUntil(() => u.isVisible(chatroomview));
chatroomview.close();
_converse.muc_instant_rooms = false;
api.settings.set('muc_instant_rooms', false);
const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
IQ_id = sendIQ.bind(this)(iq, callback, errback);

View File

@ -161,6 +161,7 @@ describe("Groupchats", function () {
'enable_smacks': false
}, async function (_converse) {
const { api } = _converse;
const nick = 'romeo';
const sent_IQs = _converse.connection.IQ_stanzas;
const muc_jid = 'lounge@montague.lit'
@ -241,7 +242,7 @@ describe("Groupchats", function () {
</message>`);
_converse.connection._dataRecv(mock.createRequest(message));
const affs = _converse.muc_fetch_members;
const affs = api.settings.get('muc_fetch_members');
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
await mock.returnMemberLists(_converse, muc_jid, [], all_affiliations);

View File

@ -94,8 +94,9 @@ describe("Notifications", function () {
expect(window.Notification).toHaveBeenCalled();
}));
it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse((_converse) => {
_converse.allow_non_roster_messaging = false;
it("is not shown for full JID headline messages if allow_non_roster_messaging is false",
mock.initConverse([], {'allow_non_roster_messaging': false}, (_converse) => {
const stub = jasmine.createSpyObj('MyNotification', ['onclick', 'close']);
spyOn(window, 'Notification').and.returnValue(stub);
const stanza = $msg({

View File

@ -144,7 +144,7 @@ export function showFeedbackNotification (data) {
const n = new Notification(data.subject, {
body: data.message,
lang: _converse.locale,
icon: _converse.notification_icon
icon: api.settings.get('notification_icon')
});
setTimeout(n.close.bind(n), 5000);
}
@ -155,7 +155,7 @@ export function showFeedbackNotification (data) {
* contact's chat state.
*/
function showChatStateNotification (contact) {
if (_converse.chatstate_notification_blacklist.includes(contact.jid)) {
if (api.settings.get('chatstate_notification_blacklist')?.includes(contact.jid)) {
// Don't notify if the user is being ignored.
return;
}
@ -176,7 +176,7 @@ function showChatStateNotification (contact) {
const n = new Notification(contact.getDisplayName(), {
body: message,
lang: _converse.locale,
icon: _converse.notification_icon
icon: api.settings.get('notification_icon')
});
setTimeout(() => n.close(), 5000);
}
@ -243,7 +243,7 @@ function showMessageNotification (data) {
'body': body,
'lang': _converse.locale,
'icon': api.settings.get('notification_icon'),
'requireInteraction': !_converse.notification_delay
'requireInteraction': !api.settings.get('notification_delay')
});
if (api.settings.get('notification_delay')) {
setTimeout(() => n.close(), api.settings.get('notification_delay'));
@ -315,7 +315,7 @@ function showContactRequestNotification (contact) {
const n = new Notification(contact.getDisplayName(), {
body: __('wants to be your contact'),
lang: _converse.locale,
icon: _converse.notification_icon
icon: api.settings.get('notification_icon')
});
setTimeout(() => n.close(), 5000);
}

View File

@ -20,11 +20,12 @@ describe("XEP-0357 Push Notifications", function () {
}]
}, async function (_converse) {
const { api } = _converse;
const IQ_stanzas = _converse.connection.IQ_stanzas;
expect(_converse.session.get('push_enabled')).toBeFalsy();
await mock.waitUntilDiscoConfirmed(
_converse, _converse.push_app_servers[0].jid,
_converse, api.settings.get('push_app_servers')[0].jid,
[{'category': 'pubsub', 'type':'push'}],
['urn:xmpp:push:0'], [], 'info');
await mock.waitUntilDiscoConfirmed(
@ -58,9 +59,10 @@ describe("XEP-0357 Push Notifications", function () {
}]
}, async function (_converse) {
const { api } = _converse;
const IQ_stanzas = _converse.connection.IQ_stanzas;
await mock.waitUntilDiscoConfirmed(
_converse, _converse.push_app_servers[0].jid,
_converse, api.settings.get('push_app_servers')[0].jid,
[{'category': 'pubsub', 'type':'push'}],
['urn:xmpp:push:0'], [], 'info');
await mock.waitUntilDiscoConfirmed(
@ -144,11 +146,12 @@ describe("XEP-0357 Push Notifications", function () {
}]
}, async function (_converse) {
const { api } = _converse;
const IQ_stanzas = _converse.connection.IQ_stanzas;
expect(_converse.session.get('push_enabled')).toBeFalsy();
await mock.waitUntilDiscoConfirmed(
_converse, _converse.push_app_servers[0].jid,
_converse, api.settings.get('push_app_servers')[0].jid,
[{'category': 'pubsub', 'type':'push'}],
['urn:xmpp:push:0'], [], 'info');
await mock.waitUntilDiscoConfirmed(

View File

@ -7,7 +7,7 @@
*/
import "@converse/headless/plugins/muc/index.js";
import './view.js';
import { _converse, api, converse } from "@converse/headless/core";
import { api, converse } from "@converse/headless/core";
converse.plugins.add('converse-roomslist', {
@ -17,7 +17,7 @@ converse.plugins.add('converse-roomslist', {
initialize () {
// Event handlers
api.listen.on('connected', async () => {
if (_converse.allow_bookmarks) {
if (api.settings.get('allow_bookmarks')) {
await api.waitUntil('bookmarksInitialized');
} else {
await Promise.all([

View File

@ -44,7 +44,7 @@ const room_item = (o) => {
title="${__('Click to open this groupchat')}"
@click=${o.openRoom}>${o.room.getDisplayName()}</a>
${ o.allow_bookmarks ? bookmark(o) : '' }
${ api.settings.get('allow_bookmarks') ? bookmark(o) : '' }
<a class="list-item-action room-info fa fa-info-circle"
data-room-jid="${o.room.get('jid')}"

View File

@ -40,7 +40,7 @@ export class RoomsList extends ElementView {
render () {
render(tpl_roomslist({
'addBookmark': ev => this.addBookmark(ev),
'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks,
'allow_bookmarks': api.settings.get('allow_bookmarks') && _converse.bookmarks,
'closeRoom': ev => this.closeRoom(ev),
'collapsed': this.model.get('toggle-state') !== _converse.OPENED,
'currently_open': room => _converse.isUniView() && !room.get('hidden'),

View File

@ -7,8 +7,9 @@ describe("Converse", function() {
it("Can be inserted into a converse-root custom element after having been initialized",
mock.initConverse([], {'root': new DocumentFragment()}, async (_converse) => {
const { api } = _converse;
expect(document.body.querySelector('#conversejs')).toBe(null);
expect(_converse.root.firstElementChild.nodeName.toLowerCase()).toBe('converse-root');
expect(api.settings.get('root').firstElementChild.nodeName.toLowerCase()).toBe('converse-root');
document.body.appendChild(document.createElement('converse-root'));
await u.waitUntil(() => document.body.querySelector('#conversejs') !== null);
}));

View File

@ -166,7 +166,7 @@ export class RichText extends String {
this.addTemplateResult(
m.index + offset,
m.index + m[0].length + offset,
getHyperlinkTemplate(m[0].replace(regex, _converse.geouri_replacement))
getHyperlinkTemplate(m[0].replace(regex, api.settings.get('geouri_replacement')))
);
}
}

View File

@ -316,7 +316,7 @@ async function openAndEnterChatRoom (_converse, muc_jid, nick, features=[], memb
const model = _converse.chatboxes.get(muc_jid);
await u.waitUntil(() => (model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
const affs = _converse.muc_fetch_members;
const affs = api.settings.get('muc_fetch_members');
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
await returnMemberLists(_converse, muc_jid, members, all_affiliations);
await model.messages.fetched;