Explorar o código

Breaking change: stop setting config variables on the _converse object

JC Brand %!s(int64=3) %!d(string=hai) anos
pai
achega
05dcb4e8d7

+ 6 - 0
CHANGES.md

@@ -14,6 +14,12 @@ Three config settings have been obsoleted:
   - show_images_inline
   - 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)
 ## 8.0.2 (Unreleased)
 
 
 - #2640: Add `beforeFetchLoginCredentials` hook
 - #2640: Add `beforeFetchLoginCredentials` hook

+ 1 - 1
src/headless/plugins/bookmarks/utils.js

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

+ 1 - 1
src/headless/plugins/status/status.js

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

+ 0 - 4
src/headless/shared/settings/utils.js

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

+ 7 - 4
src/headless/tests/converse.js

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

+ 3 - 2
src/modals/templates/add-contact.js

@@ -1,5 +1,6 @@
-import { html } from "lit";
 import { __ } from 'i18n';
 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 { 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>
                             <label class="clearfix" for="jid">${i18n_xmpp_address}:</label>
                             <div class="suggestion-box suggestion-box__jid">
                             <div class="suggestion-box suggestion-box__jid">
                                 <ul class="suggestion-box__results suggestion-box__results--above" hidden=""></ul>
                                 <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 || ''}"
                                     value="${o.jid || ''}"
                                     class="form-control suggestion-box__input"
                                     class="form-control suggestion-box__input"
                                     placeholder="${i18n_contact_placeholder}"/>
                                     placeholder="${i18n_contact_placeholder}"/>

+ 2 - 1
src/plugins/bookmark-views/tests/bookmarks.js

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

+ 1 - 1
src/plugins/bookmark-views/utils.js

@@ -6,7 +6,7 @@ import { __ } from 'i18n';
 
 
 
 
 export function getHeadingButtons (view, buttons) {
 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 bookmarked = view.model.get('bookmarked');
         const data = {
         const data = {
             'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'),
             'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'),

+ 8 - 2
src/plugins/chatview/tests/chatbox.js

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

+ 5 - 2
src/plugins/chatview/tests/messages.js

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

+ 1 - 1
src/plugins/controlbox/templates/loginpanel.js

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

+ 1 - 2
src/plugins/headlines-view/tests/headline.js

@@ -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",
     it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
         mock.initConverse(
         mock.initConverse(
-            ['chatBoxesFetched'], {}, async function (_converse) {
+            ['chatBoxesFetched'], {'allow_non_roster_messaging': false}, async function (_converse) {
 
 
         await mock.waitForRoster(_converse, 'current', 0);
         await mock.waitForRoster(_converse, 'current', 0);
         const { $msg } = converse.env;
         const { $msg } = converse.env;
-        _converse.allow_non_roster_messaging = false;
         const stanza = $msg({
         const stanza = $msg({
                 'type': 'headline',
                 'type': 'headline',
                 'from': 'andre5114@jabber.snc.ru/Spark',
                 'from': 'andre5114@jabber.snc.ru/Spark',

+ 1 - 1
src/plugins/mam-views/tests/mam.js

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

+ 2 - 2
src/plugins/muc-views/chatarea.js

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

+ 1 - 1
src/plugins/muc-views/modals/add-muc.js

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

+ 2 - 1
src/plugins/muc-views/templates/add-muc.js

@@ -1,5 +1,6 @@
 import DOMPurify from 'dompurify';
 import DOMPurify from 'dompurify';
 import { __ } from 'i18n';
 import { __ } from 'i18n';
+import { api } from '@converse/headless/core.js';
 import { html } from "lit";
 import { html } from "lit";
 import { modal_header_close_button } from "plugins/modal/templates/buttons.js"
 import { modal_header_close_button } from "plugins/modal/templates/buttons.js"
 import { unsafeHTML } from "lit/directives/unsafe-html.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}"/>
                             <input type="text" required="required" name="chatroom" class="form-control roomjid-input" placeholder="${o.chatroom_placeholder}"/>
                         </div>
                         </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.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}>
                         <input type="submit" class="btn btn-primary" name="join" value="${i18n_join || ''}" ?disabled=${o.muc_roomid_policy_error_msg}>
                     </form>
                     </form>
                 </div>
                 </div>

+ 2 - 2
src/plugins/muc-views/templates/muc-head.js

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

+ 1 - 1
src/plugins/muc-views/tests/component.js

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

+ 3 - 1
src/plugins/muc-views/tests/muc-api.js

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

+ 2 - 1
src/plugins/muc-views/tests/muc.js

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

+ 3 - 2
src/plugins/notifications/tests/notification.js

@@ -94,8 +94,9 @@ describe("Notifications", function () {
                     expect(window.Notification).toHaveBeenCalled();
                     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']);
                     const stub = jasmine.createSpyObj('MyNotification', ['onclick', 'close']);
                     spyOn(window, 'Notification').and.returnValue(stub);
                     spyOn(window, 'Notification').and.returnValue(stub);
                     const stanza = $msg({
                     const stanza = $msg({

+ 5 - 5
src/plugins/notifications/utils.js

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

+ 6 - 3
src/plugins/push/tests/push.js

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

+ 2 - 2
src/plugins/roomslist/index.js

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

+ 1 - 1
src/plugins/roomslist/templates/roomslist.js

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

+ 1 - 1
src/plugins/roomslist/view.js

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

+ 2 - 1
src/plugins/rootview/tests/root.js

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

+ 1 - 1
src/shared/rich-text.js

@@ -166,7 +166,7 @@ export class RichText extends String {
             this.addTemplateResult(
             this.addTemplateResult(
                 m.index + offset,
                 m.index + offset,
                 m.index + m[0].length + 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')))
             );
             );
         }
         }
     }
     }

+ 1 - 1
src/shared/tests/mock.js

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