From 43f1a83c761e5aedb64c58111ee0c33c8e24004e Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Pasquier <contact@jbpasquier.eu>
Date: Tue, 9 Mar 2021 12:23:45 +0100
Subject: [PATCH 01/12] fix: avoid creating already existing contacts

---
 src/solid-xmpp-chat.js | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 5e14d12..563716e 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -77,12 +77,26 @@ export const SolidXMPPChat = {
           const user = await document.querySelector('sib-auth').getUser();
           const userProfile = await store.getData(user['@id'], this.context);
           const contactsURL = await userProfile['contacts.@id'];
-          try {
-            store.post({
-              "contact": this.resource['@id'],
-              "@context": this.context
-            }, contactsURL);
-          } catch (e) {}
+          const contactInterval = setInterval(async () => {
+            let retry = false;
+            let userContacts = [];
+            for (let contact of await userProfile['contacts.ldp:contains']) {
+              if (contact) {
+                userContacts.push(await contact['contact.@id']);
+              } else {
+                retry = true;
+              }
+            }
+            if (!retry) {
+              clearInterval(contactInterval);
+              if(!userContacts.includes(this.resource['@id'])) {
+                store.post({
+                  "contact": this.resource['@id'],
+                  "@context": this.context
+                }, contactsURL);
+              }
+            }
+          }, 100);
         }
         await converse_sib.connected_deferred;
         converse_sib.service.plugins.sibChat.changeChat(
-- 
GitLab


From 8aae8505770d8cd66cd4752ae7226ebcfebd4f6a Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 14:24:41 +0100
Subject: [PATCH 02/12] feature: clean up code with prettier

---
 .prettierrc                 |   8 +
 build-scss.js               |  21 +-
 package-lock.json           |   6 +
 package.json                |   1 +
 src/index.js                |   2 +-
 src/path.js                 |   2 +-
 src/plugins/converse-rai.js | 151 +++----
 src/solid-xmpp-chat.js      | 816 +++++++++++++++++++-----------------
 8 files changed, 513 insertions(+), 494 deletions(-)
 create mode 100644 .prettierrc

diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..f272a0a
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,8 @@
+{
+    "arrowParens": "avoid",
+    "trailingComma": "es5",
+    "tabWidth": 4,
+    "singleQuote": true,
+    "quoteProps": "preserve",
+    "printWidth": 120
+}
\ No newline at end of file
diff --git a/build-scss.js b/build-scss.js
index afd914d..ea8fa43 100644
--- a/build-scss.js
+++ b/build-scss.js
@@ -3,15 +3,16 @@ const sass = require('sass');
 const fs = require('fs');
 
 sass.render({
-  file: 'src/styles/index.scss',
-  outFile: 'dist/index.css',
+    file: 'src/styles/index.scss',
+    outFile: 'dist/index.css',
 }, function(error, result) {
-  if(!error){
-    if (!fs.existsSync('dist')){
-      fs.mkdirSync('dist', { recursive: true });
+    if (!error) {
+        if (!fs.existsSync('dist')) {
+            fs.mkdirSync('dist', { recursive: true });
+        }
+        fs.writeFile('dist/index.css', String(result.css).replace(/\/lib\/solid-xmpp-chat/g, path), (e) => {
+        });
+    } else {
+        console.error(error);
     }
-    fs.writeFile('dist/index.css', String(result.css).replace(/\/lib\/solid-xmpp-chat/g, path), (e) =>{});
-  } else {
-    console.error(error);
-  }
-});
\ No newline at end of file
+});
diff --git a/package-lock.json b/package-lock.json
index ba4b4f6..3134d39 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1864,6 +1864,12 @@
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
       "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
     },
+    "prettier": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
+      "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
+      "dev": true
+    },
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
diff --git a/package.json b/package.json
index b0e3bfa..2185785 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
     "sass": "^1.32.5"
   },
   "devDependencies": {
+    "prettier": "^2.2.1",
     "watch-cli": "^0.2.3"
   },
   "scripts": {
diff --git a/src/index.js b/src/index.js
index 214aaca..52a1909 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,3 @@
 import { SolidXMPPChat } from './solid-xmpp-chat.js';
 
-export { SolidXMPPChat }
+export { SolidXMPPChat };
diff --git a/src/path.js b/src/path.js
index 92c1e6f..3d43278 100644
--- a/src/path.js
+++ b/src/path.js
@@ -1,3 +1,3 @@
-const path = "/lib/solid-xmpp-chat";
+const path = '/lib/solid-xmpp-chat';
 
 module.exports = path;
diff --git a/src/plugins/converse-rai.js b/src/plugins/converse-rai.js
index f0db84e..d52f067 100644
--- a/src/plugins/converse-rai.js
+++ b/src/plugins/converse-rai.js
@@ -1,18 +1,12 @@
-(function (root, factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(["converse"], factory);
-    } else {
-        factory(converse);
-    }
-}(this, function (converse) {
-    var Strophe, $iq, $msg, $pres, $build, b64_sha1, _ ,Backbone, dayjs, _converse;
-    var interestingServers = new Set();
-    var subscribedServers = new Set();
+(function() {
+    let Strophe, $iq, $msg, $pres, $build, b64_sha1, _, Backbone, dayjs, _converse;
+    let interestingServers = new Set();
+    let subscribedServers = new Set();
 
-    converse.plugins.add("rai", {
+    converse.plugins.add('rai', {
         'dependencies': [],
 
-        'initialize': function () {
+        'initialize': function() {
             _converse = this._converse;
 
             Strophe = converse.env.Strophe;
@@ -27,36 +21,34 @@
 
             _converse.api.settings.extend({
                 rai_notification: true,
-                rai_notification_label: "Room Activity Indicator"
+                rai_notification_label: 'Room Activity Indicator',
             });
 
-            _converse.api.listen.on('connected', function () {
+            _converse.api.listen.on('connected', function() {
                 setupRoomActivityIndicators();
             });
 
-            _converse.api.listen.on('chatRoomViewInitialized', function (view)
-            {
-                const jid = view.model.get("jid");
+            _converse.api.listen.on('chatRoomViewInitialized', function(view) {
+                const jid = view.model.get('jid');
 
-                if (view.model.get("num_unread") > 0 || view.model.get("num_unread_general") > 0) {
+                if (view.model.get('num_unread') > 0 || view.model.get('num_unread_general') > 0) {
                     emitNotification(jid);
                 }
             });
 
-            _converse.api.listen.on('raiRoomsUpdated', function (rooms) {
+            _converse.api.listen.on('raiRoomsUpdated', function(rooms) {
                 interestingServers = new Set(rooms.filter(room => room).map(Strophe.getDomainFromJid));
-                if(_converse.api.connection.connected()) {
-	            updateSubscriptions();
-	        }
+                if (_converse.api.connection.connected()) {
+                    updateSubscriptions();
+                }
             });
 
-            _converse.api.listen.on('chatBoxScrolledDown', function (view)
-            {
+            _converse.api.listen.on('chatBoxScrolledDown', function(view) {
                 const jid = view.chatbox.get('jid');
                 const id_attr = 'stanza_id ' + jid;
                 const messages = view.chatbox.messages;
 
-                if(!getUnreadStatus(jid)) {
+                if (!getUnreadStatus(jid)) {
                     return;
                 }
 
@@ -65,46 +57,41 @@
 
                     if (message.has(id_attr)) {
                         let id = message.get(id_attr);
-                        if(id != sessionStorage.getItem("rai_displayed." + jid)) {
-                            sessionStorage.setItem("rai_displayed." + jid, id);
+                        if (id != sessionStorage.getItem('rai_displayed.' + jid)) {
+                            sessionStorage.setItem('rai_displayed.' + jid, id);
                             setUnreadStatus(jid, false);
-                            setTimeout(() => sendMarker(jid, id, "displayed"), 0);
+                            setTimeout(() => sendMarker(jid, id, 'displayed'), 0);
                         }
                         break;
                     }
                 }
             });
 
-            _converse.api.listen.on('chatBoxInsertedIntoDOM', function (view)
-            {
-                const jid = view.model.get("jid");
+            _converse.api.listen.on('chatBoxInsertedIntoDOM', function(view) {
+                const jid = view.model.get('jid');
 
-                if (view.model.get("num_unread") > 0)
-                {
+                if (view.model.get('num_unread') > 0) {
                     emitNotification(jid);
                 }
 
             });
 
-            _converse.api.listen.on('message', function (data)
-            {
+            _converse.api.listen.on('message', function(data) {
                 var chatbox = data.chatbox;
                 var history = data.attrs.is_archived;
                 var sender = data.attrs.sender;
                 var body = data.attrs.body;
 
-                if (!history && body && chatbox && sender !== 'me')
-                {
-                    const alert = chatbox.get("num_unread") > 0;
-                    const notify = chatbox.get("num_unread_general") > 0;
+                if (!history && body && chatbox && sender !== 'me') {
+                    const alert = chatbox.get('num_unread') > 0;
+                    const notify = chatbox.get('num_unread_general') > 0;
 
-                    if ( alert || notify)
-                    {
-                        emitNotification(chatbox.get("jid"),  alert);
+                    if (alert || notify) {
+                        emitNotification(chatbox.get('jid'), alert);
                     }
                 }
             });
-        }
+        },
     });
 
 
@@ -112,105 +99,97 @@
         const id = Math.random().toString(36).substr(2, 9);
         _converse.connection.send(converse.env.$pres({
             to: server_name,
-            id: id
+            id: id,
         }).c('rai', {
-            'xmlns': "xmpp:prosody.im/protocol/rai"
+            'xmlns': 'xmpp:prosody.im/protocol/rai',
         }));
     }
 
     function unsubscribeServer(server_name) {
         _converse.connection.send(converse.env.$pres({
-            to: server_name, type: "unavailable"
+            to: server_name, type: 'unavailable',
         }).c('rai', {
-            'xmlns': "xmpp:prosody.im/protocol/rai"
+            'xmlns': 'xmpp:prosody.im/protocol/rai',
         }));
     }
 
     function updateSubscriptions() {
         var new_servers = new Set([...interestingServers].filter(server => !subscribedServers.has(server)));
         var obsolete_servers = new Set([...subscribedServers].filter(server => !interestingServers.has(server)));
-        for(let server of obsolete_servers) {
+        for (let server of obsolete_servers) {
             unsubscribeServer(server);
         }
-        for(let server of new_servers) {
+        for (let server of new_servers) {
             subscribeServer(server);
         }
     }
 
-    function setupRoomActivityIndicators()
-    {
+    function setupRoomActivityIndicators() {
         updateSubscriptions();
         // If we already have unread notifications stored for this session, emit them now
-        for (var i = 0; i < sessionStorage.length; i++)
-        {
-            if (sessionStorage.key(i).indexOf("rai_notify.") == 0)
-            {
+        for (var i = 0; i < sessionStorage.length; i++) {
+            if (sessionStorage.key(i).indexOf('rai_notify.') == 0) {
                 const jid = sessionStorage.key(i).substring(11);
                 emitNotification(jid);
             }
         }
 
-	// Listen for incoming RAI from the server
-        _converse.connection.addHandler(function (message) {
-            const from_jid = message.attributes.from?.nodevalue
-            const room_jid = from_jid?.split("/")[0]
+        // Listen for incoming RAI from the server
+        _converse.connection.addHandler(function(message) {
+            const from_jid = message.attributes.from?.nodevalue;
+            const room_jid = from_jid?.split('/')[0];
             const room = '';
             let ignore = false;
-            for (let i = 0; i < _converse.chatboxes.models.length; i++){
-                if(_converse.chatboxes.models[i].id === room_jid){
+            for (let i = 0; i < _converse.chatboxes.models.length; i++) {
+                if (_converse.chatboxes.models[i].id === room_jid) {
                     room = _converse.chatboxes.models[i].id;
                     break;
                 }
             }
-            if (room && from_jid && room_jid){
-                if (from_jid === room_jid+'/'+room.get('nick')){
+            if (room && from_jid && room_jid) {
+                if (from_jid === room_jid + '/' + room.get('nick')) {
                     ignore = true;
                 }
             }
-            if(message && !ignore)
-                message.querySelectorAll('activity').forEach(function (activity)
-                {
-                    if (activity && activity.namespaceURI == "xmpp:prosody.im/protocol/rai")
-                    {
+            if (message && !ignore)
+                message.querySelectorAll('activity').forEach(function(activity) {
+                    if (activity && activity.namespaceURI == 'xmpp:prosody.im/protocol/rai') {
                         const jid = activity.textContent;
                         setUnreadStatus(jid, true);
                         emitNotification(jid);
                     }
                 });
-                return true;
+            return true;
         }, null, 'message');
     }
 
-    function setUnreadStatus(jid, flag)
-    {
-        if(flag) {
-            sessionStorage.setItem("rai_notify." + jid, "true");
+    function setUnreadStatus(jid, flag) {
+        if (flag) {
+            sessionStorage.setItem('rai_notify.' + jid, 'true');
         } else {
-            sessionStorage.removeItem("rai_notify." + jid);
+            sessionStorage.removeItem('rai_notify.' + jid);
         }
     }
 
     function getUnreadStatus(jid) {
-        return sessionStorage.getItem("rai_notify." + jid) == "true";
+        return sessionStorage.getItem('rai_notify.' + jid) == 'true';
     }
 
-    function emitNotification(jid, alert)
-    {
+    function emitNotification(jid, alert) {
         _converse.api.trigger('chatRoomActivityIndicators', jid);
     }
 
-    function sendMarker(to_jid, id, type)
-    {
+    function sendMarker(to_jid, id, type) {
         const stanza = converse.env.$msg({
-          'from': _converse.connection.jid,
-          'id': Math.random().toString(36).substr(2,9),
-          'to': to_jid,
-          'type': 'groupchat'
+            'from': _converse.connection.jid,
+            'id': Math.random().toString(36).substr(2, 9),
+            'to': to_jid,
+            'type': 'groupchat',
         }).c(type, {
-          'xmlns': converse.env.Strophe.NS.MARKERS,
-          'id': id
+            'xmlns': converse.env.Strophe.NS.MARKERS,
+            'id': id,
         });
 
         _converse.api.send(stanza);
     }
-}));
+})();
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 563716e..95e2078 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -5,335 +5,339 @@ import { Sib, store, StoreMixin } from 'https://cdn.skypack.dev/@startinblox/cor
 import ComponentPath from './path.js';
 
 class Deferred {
-  constructor() {
-    this.promise = new Promise(((resolve, reject) => {
-      this.resolve = resolve;
-      this.reject = reject;
-    }).bind(this));
-    this.then = this.promise.then.bind(this.promise);
-    this.catch = this.promise.catch.bind(this.promise);
-  }
+    constructor() {
+        this.promise = new Promise(((resolve, reject) => {
+            this.resolve = resolve;
+            this.reject = reject;
+        }).bind(this));
+        this.then = this.promise.then.bind(this.promise);
+        this.catch = this.promise.catch.bind(this.promise);
+    }
 }
 
 export const SolidXMPPChat = {
-  name: 'solid-xmpp-chat',
-  use: [ StoreMixin ],
-  attributes: {
-    authentication: {
-      type: String,
-      default: 'login',
-    },
-    autoLogin: {
-      type: Boolean,
-      default: true,
-    },
-    i18n: {
-      type: String,
-      default: 'fr',
-    },
-    websocketUrl: {
-      type: String,
-      default: 'wss://jabber.happy-dev.fr/xmpp-websocket',
+    name: 'solid-xmpp-chat',
+    use: [StoreMixin],
+    attributes: {
+        authentication: {
+            type: String,
+            default: 'login',
+        },
+        autoLogin: {
+            type: Boolean,
+            default: true,
+        },
+        i18n: {
+            type: String,
+            default: 'fr',
+        },
+        websocketUrl: {
+            type: String,
+            default: 'wss://jabber.happy-dev.fr/xmpp-websocket',
+        },
     },
-  },
 
-  get extra_context() {
-    return { "foaf": 'http://xmlns.com/foaf/0.1/', "chatProfile": "http://happy-dev.fr/owl/#chatProfile", "jabberID": "foaf:jabberID" };
-  },
+    get extra_context() {
+        return {
+            'foaf': 'http://xmlns.com/foaf/0.1/',
+            'chatProfile': 'http://happy-dev.fr/owl/#chatProfile',
+            'jabberID': 'foaf:jabberID',
+        };
+    },
 
-  async created() {
-    const check_identified = await document.querySelector('sib-auth').getUserIdToken();
-    if(check_identified) {
-      this.element.attachShadow({
-        mode: "open"
-      });
-      this.importCSS(`${ComponentPath}/dist/conversejs/converse.min.css?min`);
-      this.importCSS(`${ComponentPath}/dist/index.css?min`);
-      if (window.converse_sib === undefined) {
-        this.initializeConverse();
-      }
-    } // Else, not logged in on page load (even if not on chat)
-  },
+    async created() {
+        const check_identified = await document.querySelector('sib-auth').getUserIdToken();
+        if (check_identified) {
+            this.element.attachShadow({
+                mode: 'open',
+            });
+            this.importCSS(`${ComponentPath}/dist/conversejs/converse.min.css?min`);
+            this.importCSS(`${ComponentPath}/dist/index.css?min`);
+            if (window.converse_sib === undefined) {
+                this.initializeConverse();
+            }
+        } // Else, not logged in on page load (even if not on chat)
+    },
 
-  importCSS(path) {
-    let link = document.createElement('link');
-    link.rel = 'stylesheet';
-    link.href = path;
-    this.element.shadowRoot.append(link);
-  },
+    importCSS(path) {
+        let link = document.createElement('link');
+        link.rel = 'stylesheet';
+        link.href = path;
+        this.element.shadowRoot.append(link);
+    },
 
-  empty() {
-    this.element.innerHTML = 'Loading...';
-  },
+    empty() {
+        this.element.innerHTML = 'Loading...';
+    },
 
-  async populate() {
-    if(typeof converse_sib !== 'undefined') {
-      await converse_sib.loaded_deferred;
-      if (this.resource) {
-        if (await this.resource.jabberRoom) {
-          this.jid = await this.resource['jabberID'];
-        } else {
-          this.jid = await this.resource['chatProfile.jabberID'];
-          const user = await document.querySelector('sib-auth').getUser();
-          const userProfile = await store.getData(user['@id'], this.context);
-          const contactsURL = await userProfile['contacts.@id'];
-          const contactInterval = setInterval(async () => {
-            let retry = false;
-            let userContacts = [];
-            for (let contact of await userProfile['contacts.ldp:contains']) {
-              if (contact) {
-                userContacts.push(await contact['contact.@id']);
-              } else {
-                retry = true;
-              }
-            }
-            if (!retry) {
-              clearInterval(contactInterval);
-              if(!userContacts.includes(this.resource['@id'])) {
-                store.post({
-                  "contact": this.resource['@id'],
-                  "@context": this.context
-                }, contactsURL);
-              }
-            }
-          }, 100);
-        }
-        await converse_sib.connected_deferred;
-        converse_sib.service.plugins.sibChat.changeChat(
-          this.jid,
-          await this.resource.jabberRoom,
-          this.element.shadowRoot,
-        );
-        window.dispatchEvent(new CustomEvent('read', {
-          detail: {
-            resource: {
-              "@id": this.resource['@id']
+    async populate() {
+        if (typeof converse_sib !== 'undefined') {
+            await converse_sib.loaded_deferred;
+            if (this.resource) {
+                if (await this.resource.jabberRoom) {
+                    this.jid = await this.resource['jabberID'];
+                } else {
+                    this.jid = await this.resource['chatProfile.jabberID'];
+                    const user = await document.querySelector('sib-auth').getUser();
+                    const userProfile = await store.getData(user['@id'], this.context);
+                    const contactsURL = await userProfile['contacts.@id'];
+                    const contactInterval = setInterval(async () => {
+                        let retry = false;
+                        let userContacts = [];
+                        for (let contact of await userProfile['contacts.ldp:contains']) {
+                            if (contact) {
+                                userContacts.push(await contact['contact.@id']);
+                            } else {
+                                retry = true;
+                            }
+                        }
+                        if (!retry) {
+                            clearInterval(contactInterval);
+                            if (!userContacts.includes(this.resource['@id'])) {
+                                store.post({
+                                    'contact': this.resource['@id'],
+                                    '@context': this.context,
+                                }, contactsURL);
+                            }
+                        }
+                    }, 100);
+                }
+                await converse_sib.connected_deferred;
+                converse_sib.service.plugins.sibChat.changeChat(
+                    this.jid,
+                    await this.resource.jabberRoom,
+                    this.element.shadowRoot,
+                );
+                window.dispatchEvent(new CustomEvent('read', {
+                    detail: {
+                        resource: {
+                            '@id': this.resource['@id'],
+                        },
+                    },
+                }));
             }
-          }
-        }));
-      }
-    } // Else, not logged in, on chat change
-  },
+        } // Else, not logged in, on chat change
+    },
 
-  initializeConverse() {
-    window.converse_sib = {};
+    initializeConverse() {
+        window.converse_sib = {};
 
-    // Deferred resolved at the end of this function
-    converse_sib.loaded_deferred = new Deferred();
+        // Deferred resolved at the end of this function
+        converse_sib.loaded_deferred = new Deferred();
 
-    // Deferred resolved after converse.initialize
-    converse_sib.connected_deferred = new Deferred();
+        // Deferred resolved after converse.initialize
+        converse_sib.connected_deferred = new Deferred();
 
-    // Registering window.converse_sib.service
-    converse_sib.service = {
-      'waitUntilLoaded': converse_sib.loaded_deferred.promise,
-      'initialize': function (options) {
-        this.waitUntilLoaded().done(this.api.initialize, options);
-      },
-      'waitUntilConnected': converse_sib.connected_deferred.promise,
-      'plugins': {}
-    };
+        // Registering window.converse_sib.service
+        converse_sib.service = {
+            'waitUntilLoaded': converse_sib.loaded_deferred.promise,
+            'initialize': function(options) {
+                this.waitUntilLoaded().done(this.api.initialize, options);
+            },
+            'waitUntilConnected': converse_sib.connected_deferred.promise,
+            'plugins': {},
+        };
 
-    for(var key in sessionStorage){
-        if(sessionStorage.hasOwnProperty(key) && /converse/.test(key)){
-            sessionStorage.removeItem(key);
+        for (var key in sessionStorage) {
+            if (sessionStorage.hasOwnProperty(key) && /converse/.test(key)) {
+                sessionStorage.removeItem(key);
+            }
         }
-    }
-    for(var key in localStorage){
-        if(localStorage.hasOwnProperty(key) && /converse/.test(key)){
-            localStorage.removeItem(key);
+        for (var key in localStorage) {
+            if (localStorage.hasOwnProperty(key) && /converse/.test(key)) {
+                localStorage.removeItem(key);
+            }
         }
-    }
-    indexedDB.deleteDatabase('converse-persistent');
+        indexedDB.deleteDatabase('converse-persistent');
 
-    // Alias for solid-xmpp-chat use # want to un-expose converse from window later
-    // window.converse_sib.service.api === window.converse
-    converse_sib.service.api = converse;
+        // Alias for solid-xmpp-chat use # want to un-expose converse from window later
+        // window.converse_sib.service.api === window.converse
+        converse_sib.service.api = converse;
 
-    // Change chat plugin
-    converse_sib.service.plugins.sibChat = new(class {
-      changeChat(jid, is_groupchat, root) {
-        // function isEmptyMessage (attrs) {
-        //   if (attrs && attrs.attributes) {
-        //       attrs = attrs.attributes;
-        //   }
-        //   return !attrs['oob_url'] &&
-        //       !attrs['file'] &&
-        //       !(attrs['is_encrypted'] && attrs['plaintext']) &&
-        //       !attrs['message'];
-        // };
+        // Change chat plugin
+        converse_sib.service.plugins.sibChat = new (class {
+            changeChat(jid, is_groupchat, root) {
+                // function isEmptyMessage (attrs) {
+                //   if (attrs && attrs.attributes) {
+                //       attrs = attrs.attributes;
+                //   }
+                //   return !attrs['oob_url'] &&
+                //       !attrs['file'] &&
+                //       !(attrs['is_encrypted'] && attrs['plaintext']) &&
+                //       !attrs['message'];
+                // };
 
-        // function removeUnnecessaryDayIndicators(view) {
-        //   const pred = (el) =>
-        //     el.matches('.date-separator') && el.nextElementSibling.matches('.date-separator');
-        //   const container = view.el.querySelector('.chat-content__messages');
-        //   const to_remove = Array.from(container.children).filter(pred);
-        //   to_remove.forEach((el) => el.parentElement.removeChild(el));
-        // };
-        // function isHidden(classList){
-        //   for(let i = 0; i < classList.length; i++){
-        //     if(classList[i] === 'hidden'){
-        //       return true;
-        //     }
-        //   }
-        //   return false;
-        // }
-        if (!jid) {
-          return;
-        }
-        jid = jid.toLowerCase();
-        this._converse.root = root;
+                // function removeUnnecessaryDayIndicators(view) {
+                //   const pred = (el) =>
+                //     el.matches('.date-separator') && el.nextElementSibling.matches('.date-separator');
+                //   const container = view.el.querySelector('.chat-content__messages');
+                //   const to_remove = Array.from(container.children).filter(pred);
+                //   to_remove.forEach((el) => el.parentElement.removeChild(el));
+                // };
+                // function isHidden(classList){
+                //   for(let i = 0; i < classList.length; i++){
+                //     if(classList[i] === 'hidden'){
+                //       return true;
+                //     }
+                //   }
+                //   return false;
+                // }
+                if (!jid) {
+                    return;
+                }
+                jid = jid.toLowerCase();
+                this._converse.root = root;
 
-        // Get the current used solid-xmpp-chat
-        const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
-          .map(el => el.shadowRoot.getElementById('conversejs'))
-          .filter(el => el)
-          .pop();
+                // Get the current used solid-xmpp-chat
+                const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
+                    .map(el => el.shadowRoot.getElementById('conversejs'))
+                    .filter(el => el)
+                    .pop();
 
-        if (converse_el) {
-          root.appendChild(converse_el);
-          // if (is_groupchat) {
-          //   const jid_to_clear = converse_el.getElementsByClassName('converse-chatboxes');
-          //   let room_to_clear_view = '';
-          //   if (jid_to_clear.length && jid_to_clear[0].children.length){
-          //     for (let i = 0; i < jid_to_clear[0].children.length; i++) {
-          //         if(!isHidden(jid_to_clear[0].children[i].classList)){
-          //           room_to_clear_view = this._converse.chatboxviews.views[jid_to_clear[0].children[i].id.split('-')[1]];
-          //           break;
-          //         }
-          //     }
-          //   }
-          //   if (room_to_clear_view) {
-          //     if (room_to_clear_view.model.messages.length > 30) {
-          //       const non_empty_messages = room_to_clear_view.model.messages.filter((m) => !isEmptyMessage(m));
-          //       if (non_empty_messages.length > 30) {
-          //       while (non_empty_messages.length > 30) {
-          //           non_empty_messages.shift().destroy();
-          //       }
-          //       removeUnnecessaryDayIndicators(room_to_clear_view);
-          //       }
-          //     }
-          //   }
-          // }
-        }
-        if (is_groupchat) {
-          this._converse.api.rooms.open(jid, {}, true);
-        } else {
-          this._converse.api.chats.open(jid, {}, true);
-        }
-      }
-    });
-    // Initialize deferred resolution plugin
-    setTimeout(async () => {
-      // Initialize change change plugin
-      converse.plugins.add('conversejs-changechat', converse_sib.service.plugins.sibChat);
+                if (converse_el) {
+                    root.appendChild(converse_el);
+                    // if (is_groupchat) {
+                    //   const jid_to_clear = converse_el.getElementsByClassName('converse-chatboxes');
+                    //   let room_to_clear_view = '';
+                    //   if (jid_to_clear.length && jid_to_clear[0].children.length){
+                    //     for (let i = 0; i < jid_to_clear[0].children.length; i++) {
+                    //         if(!isHidden(jid_to_clear[0].children[i].classList)){
+                    //           room_to_clear_view = this._converse.chatboxviews.views[jid_to_clear[0].children[i].id.split('-')[1]];
+                    //           break;
+                    //         }
+                    //     }
+                    //   }
+                    //   if (room_to_clear_view) {
+                    //     if (room_to_clear_view.model.messages.length > 30) {
+                    //       const non_empty_messages = room_to_clear_view.model.messages.filter((m) => !isEmptyMessage(m));
+                    //       if (non_empty_messages.length > 30) {
+                    //       while (non_empty_messages.length > 30) {
+                    //           non_empty_messages.shift().destroy();
+                    //       }
+                    //       removeUnnecessaryDayIndicators(room_to_clear_view);
+                    //       }
+                    //     }
+                    //   }
+                    // }
+                }
+                if (is_groupchat) {
+                    this._converse.api.rooms.open(jid, {}, true);
+                } else {
+                    this._converse.api.chats.open(jid, {}, true);
+                }
+            }
+        });
+        // Initialize deferred resolution plugin
+        setTimeout(async () => {
+            // Initialize change change plugin
+            converse.plugins.add('conversejs-changechat', converse_sib.service.plugins.sibChat);
 
-      // Initialize deferred resolution plugin
-      converse.plugins.add('conversejs-sib-connected', {
-        initialize() {
-          this._converse.api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
-        }
-      });
+            // Initialize deferred resolution plugin
+            converse.plugins.add('conversejs-sib-connected', {
+                initialize() {
+                    this._converse.api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
+                },
+            });
 
-      // Initialize AUTHFAIL plugin
-      converse.plugins.add('conversejs-sib-disconnected', {
-        initialize() {
-          this._converse.api.listen.on('disconnected', () => {
-            if(this._converse.connfeedback.attributes.connection_status === converse.env.Strophe.Status.AUTHFAIL) {
-              Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
-                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`
-              );
-            } else {
-              Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
-                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${this._converse.connfeedback.attributes.message}</i></div>`
-              );
-            }
-          });
-        }
-      });
+            // Initialize AUTHFAIL plugin
+            converse.plugins.add('conversejs-sib-disconnected', {
+                initialize() {
+                    this._converse.api.listen.on('disconnected', () => {
+                        if (this._converse.connfeedback.attributes.connection_status === converse.env.Strophe.Status.AUTHFAIL) {
+                            Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
+                                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`,
+                            );
+                        } else {
+                            Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
+                                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${this._converse.connfeedback.attributes.message}</i></div>`,
+                            );
+                        }
+                    });
+                },
+            });
 
-      // Initialize rai plugin
-      converse.plugins.add('conversejs-rai', {
-        async initialize() {
+            // Initialize rai plugin
+            converse.plugins.add('conversejs-rai', {
+                async initialize() {
 
-          let userRooms = (await Promise.all([
-            new Promise((resolve, reject) => {
-              const circleInterval = setInterval(async () => {
-                let retry = false;
-                let circles = [];
-                const user = await document.querySelector('sib-auth').getUser();
-                const userProfile = await store.getData(user['@id'], this.context);
-                for (let circleMembership of await userProfile['circles.ldp:contains']) {
-                  if (circleMembership) {
-                    circles.push(await circleMembership['circle.jabberID']);
-                  } else {
-                    retry = true;
-                  }
-                }
-                if (!retry) {
-                  clearInterval(circleInterval);
-                  resolve(circles);
-                }
-              }, 250);
-            }),
-            new Promise((resolve, reject) => {
-              const projectInterval = setInterval(async () => {
-                let retry = false;
-                let projects = [];
-                const user = await document.querySelector('sib-auth').getUser();
-                const userProfile = await store.getData(user['@id'], this.context);
-                for (let projectMembership of await userProfile['projects.ldp:contains']) {
-                  if (projectMembership) {
-                    projects.push(await projectMembership['project.jabberID']);
-                  } else {
-                    retry = true;
-                  }
-                }
-                if (!retry) {
-                  clearInterval(projectInterval);
-                  resolve(projects);
-                }
-              }, 250);
-            })
-          ])).flat();
+                    let userRooms = (await Promise.all([
+                        new Promise((resolve, reject) => {
+                            const circleInterval = setInterval(async () => {
+                                let retry = false;
+                                let circles = [];
+                                const user = await document.querySelector('sib-auth').getUser();
+                                const userProfile = await store.getData(user['@id'], this.context);
+                                for (let circleMembership of await userProfile['circles.ldp:contains']) {
+                                    if (circleMembership) {
+                                        circles.push(await circleMembership['circle.jabberID']);
+                                    } else {
+                                        retry = true;
+                                    }
+                                }
+                                if (!retry) {
+                                    clearInterval(circleInterval);
+                                    resolve(circles);
+                                }
+                            }, 250);
+                        }),
+                        new Promise((resolve, reject) => {
+                            const projectInterval = setInterval(async () => {
+                                let retry = false;
+                                let projects = [];
+                                const user = await document.querySelector('sib-auth').getUser();
+                                const userProfile = await store.getData(user['@id'], this.context);
+                                for (let projectMembership of await userProfile['projects.ldp:contains']) {
+                                    if (projectMembership) {
+                                        projects.push(await projectMembership['project.jabberID']);
+                                    } else {
+                                        retry = true;
+                                    }
+                                }
+                                if (!retry) {
+                                    clearInterval(projectInterval);
+                                    resolve(projects);
+                                }
+                            }, 250);
+                        }),
+                    ])).flat();
 
-          // @MattJ Here userRooms is an array of each jabberID the user is on.
-          this._converse.api.trigger('raiRoomsUpdated', userRooms);
+                    // @MattJ Here userRooms is an array of each jabberID the user is on.
+                    this._converse.api.trigger('raiRoomsUpdated', userRooms);
 
-          this._converse.api.listen.on('chatRoomActivityIndicators', function (jid) {
-            window.dispatchEvent(new CustomEvent('newMessage', {
-              detail: {
-                jid: jid
-              }
-            }));
-          });
-        }
-      });
+                    this._converse.api.listen.on('chatRoomActivityIndicators', function(jid) {
+                        window.dispatchEvent(new CustomEvent('newMessage', {
+                            detail: {
+                                jid: jid,
+                            },
+                        }));
+                    });
+                },
+            });
 
-      // Transform hats to custom values
-      converse.plugins.add('custom-hats', {
-        overrides: {
-          getHats: function () {
-            const hat_conversions = {'admin': 'Administrateur'};
-            const _converse = this;
-            const hats = _converse.__super__.getHats.apply(this, arguments);
-            if (!hat_conversions) {
-              return hats;
-            } else {
-              const role_affiliations = Object.keys(hat_conversions);
-              const custom_hats = hats.map((hat) => {
-                if (role_affiliations.includes(hat.title)){
-                    return({title: hat_conversions[hat.title]});
-                } else {
-                    return hat;
-                }
-              })
-              return custom_hats
-            }
-          }
-        }
-      });
-      //Highly experimental DO NOT USE
+            // Transform hats to custom values
+            converse.plugins.add('custom-hats', {
+                overrides: {
+                    getHats: function() {
+                        const hat_conversions = { 'admin': 'Administrateur' };
+                        const _converse = this;
+                        const hats = _converse.__super__.getHats.apply(this, arguments);
+                        if (!hat_conversions) {
+                            return hats;
+                        } else {
+                            const role_affiliations = Object.keys(hat_conversions);
+                            const custom_hats = hats.map((hat) => {
+                                if (role_affiliations.includes(hat.title)) {
+                                    return ({ title: hat_conversions[hat.title] });
+                                } else {
+                                    return hat;
+                                }
+                            });
+                            return custom_hats;
+                        }
+                    },
+                },
+            });
+            //Highly experimental DO NOT USE
 //       converse.plugins.add('custom-storage', {
 //         overrides: {
 //           createStore: function () {
@@ -345,107 +349,127 @@ export const SolidXMPPChat = {
 //           }
 //         }
 //       });
-      //Override converse's request permission with an empty function
-      //so that permission request for notifications don't happen
-      converse.plugins.add('remove-notifications', {
-        overrides: {
-          requestPermission: function () {},
-          showMessageNotification: function () {},
-          showChatStateNotification: function () {},
-          showContactRequestNotification: function () {},
-          showFeedbackNotification: function () {},
-          handleChatStateNotification: function () {},
-          handleMessageNotification: function () {},
-          handleContactRequestNotification: function () {},
-          handleFeedback: function () {},
-        }
-      });
-      // Initialize deferred resolution plugin
-      converse.plugins.add('conversejs-sib-focused', {
-        initialize() {
-          this._converse.api.listen.on('chatBoxFocused', function() {
-            // Get the currently used solid-xmpp-chat & send read event of
-            const resource = Array.from(document.querySelectorAll('solid-xmpp-chat'))
-              .filter(el => {return el.shadowRoot.getElementById('conversejs')})
-              .pop()
-              .component.resource;
-            window.dispatchEvent(new CustomEvent('read', {
-              detail: {
-                resource: resource
-              }
-            }));
-          });
-        }
-      });
+            //Override converse's request permission with an empty function
+            //so that permission request for notifications don't happen
+            converse.plugins.add('remove-notifications', {
+                overrides: {
+                    requestPermission: function() {
+                    },
+                    showMessageNotification: function() {
+                    },
+                    showChatStateNotification: function() {
+                    },
+                    showContactRequestNotification: function() {
+                    },
+                    showFeedbackNotification: function() {
+                    },
+                    handleChatStateNotification: function() {
+                    },
+                    handleMessageNotification: function() {
+                    },
+                    handleContactRequestNotification: function() {
+                    },
+                    handleFeedback: function() {
+                    },
+                },
+            });
+            // Initialize deferred resolution plugin
+            converse.plugins.add('conversejs-sib-focused', {
+                initialize() {
+                    this._converse.api.listen.on('chatBoxFocused', function() {
+                        // Get the currently used solid-xmpp-chat & send read event of
+                        const resource = Array.from(document.querySelectorAll('solid-xmpp-chat'))
+                            .filter(el => {
+                                return el.shadowRoot.getElementById('conversejs');
+                            })
+                            .pop()
+                            .component.resource;
+                        window.dispatchEvent(new CustomEvent('read', {
+                            detail: {
+                                resource: resource,
+                            },
+                        }));
+                    });
+                },
+            });
 
-      const user = await document.querySelector('sib-auth').getUser();
-      const userProfile = await store.getData(user['@id'], this.context);
-      const jabberID = await userProfile['chatProfile.jabberID'];
+            const user = await document.querySelector('sib-auth').getUser();
+            const userProfile = await store.getData(user['@id'], this.context);
+            const jabberID = await userProfile['chatProfile.jabberID'];
 
-      if(this.resource) {
-        if (await this.resource.jabberRoom) {
-          this.jid = await this.resource['jabberID'];
-        } else {
-          this.jid = await this.resource['chatProfile.jabberID'];
-        }
-      } else {
-        this.jid = jabberID;
-      }
+            if (this.resource) {
+                if (await this.resource.jabberRoom) {
+                    this.jid = await this.resource['jabberID'];
+                } else {
+                    this.jid = await this.resource['chatProfile.jabberID'];
+                }
+            } else {
+                this.jid = jabberID;
+            }
 
-      const idToken = await document.querySelector('sib-auth').getUserIdToken();
+            const idToken = await document.querySelector('sib-auth').getUserIdToken();
 
-      converse.initialize({
-        'assets_path': (/skypack/.test(ComponentPath) ? ComponentPath.replace('cdn.skypack.dev', 'unpkg.com') : ComponentPath) + '/dist/conversejs/',
-        'authentication': this.element.dataset.authentication || 'login',
-        'password': idToken,
-        'allow_bookmarks': false,
-        'allow_chat_pending_contacts': true,
-        'allow_message_retraction': 'moderator',
-        'allow_non_roster_messaging': true,
-        'allow_dragresize': false,
-        'allow_logout': false,
-        'archived_messages_page_size': "30",
-        'auto_list_rooms': true,
-        'auto_login': this.element.dataset.autoLogin === 'true',
-        'auto_join_on_invite': true,
-        'auto_reconnect': true,
-        'auto_register_muc_nickname': false,
-        'websocket_url': this.element.dataset.websocketUrl || 'wss://jabber.happy-dev.fr/xmpp-websocket',
-        'enable_smacks': true,
-        "clear_messages_on_reconnection": false,
-        "discover_connection_methods": false,
-        'jid': jabberID.toLowerCase(),
-        'i18n': this.element.dataset.i18n || 'fr',
-        'loglevel': 'fatal',
-        'message_archiving': 'always',
-        'message_archiving_timeout': 60000,
-        'muc_disable_slash_commands': true,
-        'muc_hats': ['hats', 'vcard_roles', 'admin'],
-        'role_affiliation_hat_conversions': {'admin': 'Administrateur'},
-        'muc_nickname_from_jid': false,
-        'muc_fetch_members': true,
-        'muc_show_info_messages': [],
-        'play_sounds': false,
-        'root': this.element.shadowRoot,
-        'show_client_info': false,
-        'show_desktop_notifications': false,
-        'persistent_store': 'none',
-        'sounds_path': ComponentPath + '/dist/conversejs/',
-        'show_send_button': false,
-        'view_mode': 'fullscreen',
-        'visible_toolbar_buttons': {
-          call: false,
-          spoiler: false,
-          emoji: true,
-          fileupload: true, // Not working in current Converse
-          toggle_occupants: false
-        },
-        'whitelisted_plugins': ['rai', 'conversejs-sib-disconnected', 'conversejs-sib-connected', 'conversejs-sib-focused', 'conversejs-changechat', 'conversejs-rai', 'custom-hats', 'remove-notifications'],
-      });
+            converse.initialize({
+                'assets_path': (/skypack/.test(ComponentPath) ? ComponentPath.replace('cdn.skypack.dev', 'unpkg.com') : ComponentPath) + '/dist/conversejs/',
+                'authentication': this.element.dataset.authentication || 'login',
+                'password': idToken,
+                'allow_bookmarks': false,
+                'allow_chat_pending_contacts': true,
+                'allow_message_retraction': 'moderator',
+                'allow_non_roster_messaging': true,
+                'allow_dragresize': false,
+                'allow_logout': false,
+                'archived_messages_page_size': '30',
+                'auto_list_rooms': true,
+                'auto_login': this.element.dataset.autoLogin === 'true',
+                'auto_join_on_invite': true,
+                'auto_reconnect': true,
+                'auto_register_muc_nickname': false,
+                'websocket_url': this.element.dataset.websocketUrl || 'wss://jabber.happy-dev.fr/xmpp-websocket',
+                'enable_smacks': true,
+                'clear_messages_on_reconnection': false,
+                'discover_connection_methods': false,
+                'jid': jabberID.toLowerCase(),
+                'i18n': this.element.dataset.i18n || 'fr',
+                'loglevel': 'fatal',
+                'message_archiving': 'always',
+                'message_archiving_timeout': 60000,
+                'muc_disable_slash_commands': true,
+                'muc_hats': ['hats', 'vcard_roles', 'admin'],
+                'role_affiliation_hat_conversions': { 'admin': 'Administrateur' },
+                'muc_nickname_from_jid': false,
+                'muc_fetch_members': true,
+                'muc_show_info_messages': [],
+                'play_sounds': false,
+                'root': this.element.shadowRoot,
+                'show_client_info': false,
+                'show_desktop_notifications': false,
+                'persistent_store': 'none',
+                'sounds_path': ComponentPath + '/dist/conversejs/',
+                'show_send_button': false,
+                'view_mode': 'fullscreen',
+                'visible_toolbar_buttons': {
+                    call: false,
+                    spoiler: false,
+                    emoji: true,
+                    fileupload: true, // Not working in current Converse
+                    toggle_occupants: false,
+                },
+                'whitelisted_plugins': [
+                    'rai',
+                    'conversejs-sib-disconnected',
+                    'conversejs-sib-connected',
+                    'conversejs-sib-focused',
+                    'conversejs-changechat',
+                    'conversejs-rai',
+                    'custom-hats',
+                    'remove-notifications',
+                ],
+            });
 
-      converse_sib.loaded_deferred.resolve();
-    }, 0);
-  }
+            converse_sib.loaded_deferred.resolve();
+        }, 0);
+    },
 };
 
 Sib.register(SolidXMPPChat);
-- 
GitLab


From 111b1f573909e3701eabfb836c14fd35112107e7 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 14:38:43 +0100
Subject: [PATCH 03/12] move deferred into utils and some plugins into the
 plugins folder

---
 src/plugins/sib-custom-hats.js          | 23 +++++++
 src/plugins/sib-remove-notifications.js | 26 ++++++++
 src/solid-xmpp-chat.js                  | 81 +++----------------------
 src/utils.js                            | 10 +++
 4 files changed, 67 insertions(+), 73 deletions(-)
 create mode 100644 src/plugins/sib-custom-hats.js
 create mode 100644 src/plugins/sib-remove-notifications.js
 create mode 100644 src/utils.js

diff --git a/src/plugins/sib-custom-hats.js b/src/plugins/sib-custom-hats.js
new file mode 100644
index 0000000..334097d
--- /dev/null
+++ b/src/plugins/sib-custom-hats.js
@@ -0,0 +1,23 @@
+/**
+ * Transform hats to custom values.
+ */
+converse.plugins.add('sib-custom-hats', {
+    overrides: {
+        getHats: function() {
+            const hat_conversions = { 'admin': 'Administrateur' };
+            const hats = this.__super__.getHats.apply(this, arguments);
+            if (!hat_conversions) {
+                return hats;
+            } else {
+                const role_affiliations = Object.keys(hat_conversions);
+                return hats.map((hat) => {
+                    if (role_affiliations.includes(hat.title)) {
+                        return ({ title: hat_conversions[hat.title] });
+                    } else {
+                        return hat;
+                    }
+                });
+            }
+        },
+    },
+});
diff --git a/src/plugins/sib-remove-notifications.js b/src/plugins/sib-remove-notifications.js
new file mode 100644
index 0000000..dd11271
--- /dev/null
+++ b/src/plugins/sib-remove-notifications.js
@@ -0,0 +1,26 @@
+/**
+ * Override converse's request permission with an empty function
+ * so that permission request for notifications don't happen.
+ */
+converse.plugins.add('sib-remove-notifications', {
+    overrides: {
+        requestPermission: function() {
+        },
+        showMessageNotification: function() {
+        },
+        showChatStateNotification: function() {
+        },
+        showContactRequestNotification: function() {
+        },
+        showFeedbackNotification: function() {
+        },
+        handleChatStateNotification: function() {
+        },
+        handleMessageNotification: function() {
+        },
+        handleContactRequestNotification: function() {
+        },
+        handleFeedback: function() {
+        },
+    },
+});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 95e2078..accf5e8 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -1,19 +1,13 @@
-import './conversejs/converse.min.js';
-import './conversejs/emojis.js';
-import './plugins/converse-rai.js';
 import { Sib, store, StoreMixin } from 'https://cdn.skypack.dev/@startinblox/core@0.15';
+import { Deferred } from './utils.js';
 import ComponentPath from './path.js';
 
-class Deferred {
-    constructor() {
-        this.promise = new Promise(((resolve, reject) => {
-            this.resolve = resolve;
-            this.reject = reject;
-        }).bind(this));
-        this.then = this.promise.then.bind(this.promise);
-        this.catch = this.promise.catch.bind(this.promise);
-    }
-}
+import './conversejs/converse.min.js';
+import './conversejs/emojis.js';
+
+import './plugins/converse-rai.js';
+import './plugins/sib-custom-hats.js';
+import './plugins/sib-remove-notifications.js';
 
 export const SolidXMPPChat = {
     name: 'solid-xmpp-chat',
@@ -314,65 +308,6 @@ export const SolidXMPPChat = {
                 },
             });
 
-            // Transform hats to custom values
-            converse.plugins.add('custom-hats', {
-                overrides: {
-                    getHats: function() {
-                        const hat_conversions = { 'admin': 'Administrateur' };
-                        const _converse = this;
-                        const hats = _converse.__super__.getHats.apply(this, arguments);
-                        if (!hat_conversions) {
-                            return hats;
-                        } else {
-                            const role_affiliations = Object.keys(hat_conversions);
-                            const custom_hats = hats.map((hat) => {
-                                if (role_affiliations.includes(hat.title)) {
-                                    return ({ title: hat_conversions[hat.title] });
-                                } else {
-                                    return hat;
-                                }
-                            });
-                            return custom_hats;
-                        }
-                    },
-                },
-            });
-            //Highly experimental DO NOT USE
-//       converse.plugins.add('custom-storage', {
-//         overrides: {
-//           createStore: function () {
-//             const _converse = this;
-//             if (arguments.length > 1){
-//                 arguments[1] = "none";
-//             }
-//             return _converse.__super__.createStore.apply(this, arguments);
-//           }
-//         }
-//       });
-            //Override converse's request permission with an empty function
-            //so that permission request for notifications don't happen
-            converse.plugins.add('remove-notifications', {
-                overrides: {
-                    requestPermission: function() {
-                    },
-                    showMessageNotification: function() {
-                    },
-                    showChatStateNotification: function() {
-                    },
-                    showContactRequestNotification: function() {
-                    },
-                    showFeedbackNotification: function() {
-                    },
-                    handleChatStateNotification: function() {
-                    },
-                    handleMessageNotification: function() {
-                    },
-                    handleContactRequestNotification: function() {
-                    },
-                    handleFeedback: function() {
-                    },
-                },
-            });
             // Initialize deferred resolution plugin
             converse.plugins.add('conversejs-sib-focused', {
                 initialize() {
@@ -463,7 +398,7 @@ export const SolidXMPPChat = {
                     'conversejs-changechat',
                     'conversejs-rai',
                     'custom-hats',
-                    'remove-notifications',
+                    'sib-remove-notifications',
                 ],
             });
 
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..68e3bce
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,10 @@
+export class Deferred {
+    constructor() {
+        this.promise = new Promise(((resolve, reject) => {
+            this.resolve = resolve;
+            this.reject = reject;
+        }).bind(this));
+        this.then = this.promise.then.bind(this.promise);
+        this.catch = this.promise.catch.bind(this.promise);
+    }
+}
-- 
GitLab


From f61cd9914068512293eabad2075b9defa316bd4b Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:01:11 +0100
Subject: [PATCH 04/12] move sib rai plugin into its own file

---
 src/plugins/converse-rai.js         |   2 +-
 src/plugins/sib-subscribe-to-rai.js |  68 ++++++++++++++++
 src/solid-xmpp-chat.js              | 116 ++--------------------------
 3 files changed, 76 insertions(+), 110 deletions(-)
 create mode 100644 src/plugins/sib-subscribe-to-rai.js

diff --git a/src/plugins/converse-rai.js b/src/plugins/converse-rai.js
index d52f067..24ed1ad 100644
--- a/src/plugins/converse-rai.js
+++ b/src/plugins/converse-rai.js
@@ -3,7 +3,7 @@
     let interestingServers = new Set();
     let subscribedServers = new Set();
 
-    converse.plugins.add('rai', {
+    converse.plugins.add('converse-rai', {
         'dependencies': [],
 
         'initialize': function() {
diff --git a/src/plugins/sib-subscribe-to-rai.js b/src/plugins/sib-subscribe-to-rai.js
new file mode 100644
index 0000000..fee52f6
--- /dev/null
+++ b/src/plugins/sib-subscribe-to-rai.js
@@ -0,0 +1,68 @@
+/**
+ * Initialize rai plugin.
+ */
+converse.plugins.add('sib-subscribe-to-rai', {
+    dependencies: [
+        'converse-rai',
+    ],
+    async initialize() {
+        const _converse = this._converse;
+        const { api } = _converse;
+
+        const getCircles = new Promise((resolve, reject) => {
+            const circleInterval = setInterval(async () => {
+                let retry = false;
+                let circles = [];
+                const user = await document.querySelector('sib-auth').getUser();
+                const userProfile = await store.getData(user['@id'], this.context);
+                for (let circleMembership of await userProfile['circles.ldp:contains']) {
+                    if (circleMembership) {
+                        circles.push(await circleMembership['circle.jabberID']);
+                    } else {
+                        retry = true;
+                    }
+                }
+                if (!retry) {
+                    clearInterval(circleInterval);
+                    resolve(circles);
+                }
+            }, 250);
+        });
+
+        const getProjects = new Promise((resolve, reject) => {
+            const projectInterval = setInterval(async () => {
+                let retry = false;
+                let projects = [];
+                const user = await document.querySelector('sib-auth').getUser();
+                const userProfile = await store.getData(user['@id'], this.context);
+                for (let projectMembership of await userProfile['projects.ldp:contains']) {
+                    if (projectMembership) {
+                        projects.push(await projectMembership['project.jabberID']);
+                    } else {
+                        retry = true;
+                    }
+                }
+                if (!retry) {
+                    clearInterval(projectInterval);
+                    resolve(projects);
+                }
+            }, 250);
+        });
+
+        let userRooms = (await Promise.all([
+            getCircles,
+            getProjects,
+        ])).flat();
+
+        // @MattJ Here userRooms is an array of each jabberID the user is on.
+        api.trigger('raiRoomsUpdated', userRooms);
+
+        api.listen.on('chatRoomActivityIndicators', jid => {
+            window.dispatchEvent(new CustomEvent('newMessage', {
+                detail: {
+                    jid,
+                },
+            }));
+        });
+    },
+});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index accf5e8..897a368 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -8,6 +8,7 @@ import './conversejs/emojis.js';
 import './plugins/converse-rai.js';
 import './plugins/sib-custom-hats.js';
 import './plugins/sib-remove-notifications.js';
+import './plugins/sib-subscribe-to-rai.js';
 
 export const SolidXMPPChat = {
     name: 'solid-xmpp-chat',
@@ -151,34 +152,10 @@ export const SolidXMPPChat = {
         // Change chat plugin
         converse_sib.service.plugins.sibChat = new (class {
             changeChat(jid, is_groupchat, root) {
-                // function isEmptyMessage (attrs) {
-                //   if (attrs && attrs.attributes) {
-                //       attrs = attrs.attributes;
-                //   }
-                //   return !attrs['oob_url'] &&
-                //       !attrs['file'] &&
-                //       !(attrs['is_encrypted'] && attrs['plaintext']) &&
-                //       !attrs['message'];
-                // };
-
-                // function removeUnnecessaryDayIndicators(view) {
-                //   const pred = (el) =>
-                //     el.matches('.date-separator') && el.nextElementSibling.matches('.date-separator');
-                //   const container = view.el.querySelector('.chat-content__messages');
-                //   const to_remove = Array.from(container.children).filter(pred);
-                //   to_remove.forEach((el) => el.parentElement.removeChild(el));
-                // };
-                // function isHidden(classList){
-                //   for(let i = 0; i < classList.length; i++){
-                //     if(classList[i] === 'hidden'){
-                //       return true;
-                //     }
-                //   }
-                //   return false;
-                // }
                 if (!jid) {
                     return;
                 }
+
                 jid = jid.toLowerCase();
                 this._converse.root = root;
 
@@ -190,30 +167,8 @@ export const SolidXMPPChat = {
 
                 if (converse_el) {
                     root.appendChild(converse_el);
-                    // if (is_groupchat) {
-                    //   const jid_to_clear = converse_el.getElementsByClassName('converse-chatboxes');
-                    //   let room_to_clear_view = '';
-                    //   if (jid_to_clear.length && jid_to_clear[0].children.length){
-                    //     for (let i = 0; i < jid_to_clear[0].children.length; i++) {
-                    //         if(!isHidden(jid_to_clear[0].children[i].classList)){
-                    //           room_to_clear_view = this._converse.chatboxviews.views[jid_to_clear[0].children[i].id.split('-')[1]];
-                    //           break;
-                    //         }
-                    //     }
-                    //   }
-                    //   if (room_to_clear_view) {
-                    //     if (room_to_clear_view.model.messages.length > 30) {
-                    //       const non_empty_messages = room_to_clear_view.model.messages.filter((m) => !isEmptyMessage(m));
-                    //       if (non_empty_messages.length > 30) {
-                    //       while (non_empty_messages.length > 30) {
-                    //           non_empty_messages.shift().destroy();
-                    //       }
-                    //       removeUnnecessaryDayIndicators(room_to_clear_view);
-                    //       }
-                    //     }
-                    //   }
-                    // }
                 }
+
                 if (is_groupchat) {
                     this._converse.api.rooms.open(jid, {}, true);
                 } else {
@@ -221,6 +176,7 @@ export const SolidXMPPChat = {
                 }
             }
         });
+
         // Initialize deferred resolution plugin
         setTimeout(async () => {
             // Initialize change change plugin
@@ -250,64 +206,6 @@ export const SolidXMPPChat = {
                 },
             });
 
-            // Initialize rai plugin
-            converse.plugins.add('conversejs-rai', {
-                async initialize() {
-
-                    let userRooms = (await Promise.all([
-                        new Promise((resolve, reject) => {
-                            const circleInterval = setInterval(async () => {
-                                let retry = false;
-                                let circles = [];
-                                const user = await document.querySelector('sib-auth').getUser();
-                                const userProfile = await store.getData(user['@id'], this.context);
-                                for (let circleMembership of await userProfile['circles.ldp:contains']) {
-                                    if (circleMembership) {
-                                        circles.push(await circleMembership['circle.jabberID']);
-                                    } else {
-                                        retry = true;
-                                    }
-                                }
-                                if (!retry) {
-                                    clearInterval(circleInterval);
-                                    resolve(circles);
-                                }
-                            }, 250);
-                        }),
-                        new Promise((resolve, reject) => {
-                            const projectInterval = setInterval(async () => {
-                                let retry = false;
-                                let projects = [];
-                                const user = await document.querySelector('sib-auth').getUser();
-                                const userProfile = await store.getData(user['@id'], this.context);
-                                for (let projectMembership of await userProfile['projects.ldp:contains']) {
-                                    if (projectMembership) {
-                                        projects.push(await projectMembership['project.jabberID']);
-                                    } else {
-                                        retry = true;
-                                    }
-                                }
-                                if (!retry) {
-                                    clearInterval(projectInterval);
-                                    resolve(projects);
-                                }
-                            }, 250);
-                        }),
-                    ])).flat();
-
-                    // @MattJ Here userRooms is an array of each jabberID the user is on.
-                    this._converse.api.trigger('raiRoomsUpdated', userRooms);
-
-                    this._converse.api.listen.on('chatRoomActivityIndicators', function(jid) {
-                        window.dispatchEvent(new CustomEvent('newMessage', {
-                            detail: {
-                                jid: jid,
-                            },
-                        }));
-                    });
-                },
-            });
-
             // Initialize deferred resolution plugin
             converse.plugins.add('conversejs-sib-focused', {
                 initialize() {
@@ -391,13 +289,13 @@ export const SolidXMPPChat = {
                     toggle_occupants: false,
                 },
                 'whitelisted_plugins': [
-                    'rai',
+                    'converse-rai',
                     'conversejs-sib-disconnected',
                     'conversejs-sib-connected',
                     'conversejs-sib-focused',
                     'conversejs-changechat',
-                    'conversejs-rai',
-                    'custom-hats',
+                    'sib-subscribe-to-rai',
+                    'sib-custom-hats',
                     'sib-remove-notifications',
                 ],
             });
-- 
GitLab


From 56034f8f179ab724c2f88add47c22e1529a59b14 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:32:40 +0100
Subject: [PATCH 05/12] move some plugins outside of the main file

---
 src/plugins/sib-change-chat.js  |  37 ++++++++++
 src/plugins/sib-disconnected.js |  24 +++++++
 src/plugins/sib-focused.js      |  21 ++++++
 src/solid-xmpp-chat.js          | 123 +++++++++-----------------------
 4 files changed, 116 insertions(+), 89 deletions(-)
 create mode 100644 src/plugins/sib-change-chat.js
 create mode 100644 src/plugins/sib-disconnected.js
 create mode 100644 src/plugins/sib-focused.js

diff --git a/src/plugins/sib-change-chat.js b/src/plugins/sib-change-chat.js
new file mode 100644
index 0000000..7a3363a
--- /dev/null
+++ b/src/plugins/sib-change-chat.js
@@ -0,0 +1,37 @@
+/**
+ * Register a new event to move the converse element
+ * into another component.
+ */
+converse.plugins.add('sib-change-chat', {
+    initialize() {
+        const _converse = this._converse;
+        const { api } = _converse;
+
+        window.addEventListener('sib-change-chat', async ev => {
+            let { jid, is_groupchat, root } = ev.detail;
+
+            if (!jid) {
+                return;
+            }
+
+            jid = jid.toLowerCase();
+            _converse.root = root;
+
+            // Get the current used solid-xmpp-chat
+            const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
+                .map(el => el.shadowRoot.getElementById('conversejs'))
+                .filter(el => el)
+                .pop();
+
+            if (converse_el) {
+                root.appendChild(converse_el);
+            }
+
+            if (is_groupchat) {
+                await api.rooms.open(jid, {}, true);
+            } else {
+                await api.chats.open(jid, {}, true);
+            }
+        });
+    },
+});
\ No newline at end of file
diff --git a/src/plugins/sib-disconnected.js b/src/plugins/sib-disconnected.js
new file mode 100644
index 0000000..8cb6dfe
--- /dev/null
+++ b/src/plugins/sib-disconnected.js
@@ -0,0 +1,24 @@
+/**
+ * Initialize AUTHFAIL plugin
+ */
+converse.plugins.add('sib-disconnected', {
+    initialize() {
+        const _converse = this._converse;
+        const { api } = _converse;
+        const { Strophe } = converse.env;
+
+        const getChats = () => Array.from(document.querySelectorAll('solid-xmpp-chat'));
+
+        api.listen.on('disconnected', () => {
+            if (_converse.connfeedback.attributes.connection_status === Strophe.Status.AUTHFAIL) {
+                getChats().map(el => el.shadowRoot.innerHTML =
+                    `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`,
+                );
+            } else {
+                getChats().map(el => el.shadowRoot.innerHTML =
+                    `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${_converse.connfeedback.attributes.message}</i></div>`,
+                );
+            }
+        });
+    },
+});
diff --git a/src/plugins/sib-focused.js b/src/plugins/sib-focused.js
new file mode 100644
index 0000000..fb7de32
--- /dev/null
+++ b/src/plugins/sib-focused.js
@@ -0,0 +1,21 @@
+converse.plugins.add('sib-focused', {
+    initialize() {
+        const _converse = this._converse;
+        const { api } = _converse;
+
+        // Get the currently used solid-xmpp-chat
+        const getCurrentChat = () => Array.from(document.querySelectorAll('solid-xmpp-chat'))
+            .filter(el => el.shadowRoot.getElementById('conversejs'))
+            .pop();
+
+        api.listen.on('chatBoxFocused', function() {
+            const resource = getCurrentChat()?.component.resource;
+
+            window.dispatchEvent(new CustomEvent('read', {
+                detail: {
+                    resource,
+                },
+            }));
+        });
+    },
+});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 897a368..acbebbc 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -6,7 +6,10 @@ import './conversejs/converse.min.js';
 import './conversejs/emojis.js';
 
 import './plugins/converse-rai.js';
+import './plugins/sib-change-chat.js';
 import './plugins/sib-custom-hats.js';
+import './plugins/sib-disconnected.js';
+import './plugins/sib-focused.js';
 import './plugins/sib-remove-notifications.js';
 import './plugins/sib-subscribe-to-rai.js';
 
@@ -98,11 +101,15 @@ export const SolidXMPPChat = {
                     }, 100);
                 }
                 await converse_sib.connected_deferred;
-                converse_sib.service.plugins.sibChat.changeChat(
-                    this.jid,
-                    await this.resource.jabberRoom,
-                    this.element.shadowRoot,
-                );
+
+                window.dispatchEvent(new CustomEvent('sib-change-chat', {
+                    detail: {
+                        jid: this.jid,
+                        is_groupchat: await this.resource.jabberRoom,
+                        root: this.element.shadowRoot,
+                    },
+                }));
+
                 window.dispatchEvent(new CustomEvent('read', {
                     detail: {
                         resource: {
@@ -114,6 +121,20 @@ export const SolidXMPPChat = {
         } // Else, not logged in, on chat change
     },
 
+    removeConverseDatabase() {
+        for (let key in sessionStorage) {
+            if (sessionStorage.hasOwnProperty(key) && /converse/.test(key)) {
+                sessionStorage.removeItem(key);
+            }
+        }
+        for (let key in localStorage) {
+            if (localStorage.hasOwnProperty(key) && /converse/.test(key)) {
+                localStorage.removeItem(key);
+            }
+        }
+        indexedDB.deleteDatabase('converse-persistent');
+    },
+
     initializeConverse() {
         window.converse_sib = {};
 
@@ -133,96 +154,20 @@ export const SolidXMPPChat = {
             'plugins': {},
         };
 
-        for (var key in sessionStorage) {
-            if (sessionStorage.hasOwnProperty(key) && /converse/.test(key)) {
-                sessionStorage.removeItem(key);
-            }
-        }
-        for (var key in localStorage) {
-            if (localStorage.hasOwnProperty(key) && /converse/.test(key)) {
-                localStorage.removeItem(key);
-            }
-        }
-        indexedDB.deleteDatabase('converse-persistent');
+        this.removeConverseDatabase();
 
         // Alias for solid-xmpp-chat use # want to un-expose converse from window later
         // window.converse_sib.service.api === window.converse
         converse_sib.service.api = converse;
 
-        // Change chat plugin
-        converse_sib.service.plugins.sibChat = new (class {
-            changeChat(jid, is_groupchat, root) {
-                if (!jid) {
-                    return;
-                }
-
-                jid = jid.toLowerCase();
-                this._converse.root = root;
-
-                // Get the current used solid-xmpp-chat
-                const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
-                    .map(el => el.shadowRoot.getElementById('conversejs'))
-                    .filter(el => el)
-                    .pop();
-
-                if (converse_el) {
-                    root.appendChild(converse_el);
-                }
-
-                if (is_groupchat) {
-                    this._converse.api.rooms.open(jid, {}, true);
-                } else {
-                    this._converse.api.chats.open(jid, {}, true);
-                }
-            }
-        });
-
         // Initialize deferred resolution plugin
         setTimeout(async () => {
-            // Initialize change change plugin
-            converse.plugins.add('conversejs-changechat', converse_sib.service.plugins.sibChat);
-
-            // Initialize deferred resolution plugin
-            converse.plugins.add('conversejs-sib-connected', {
-                initialize() {
-                    this._converse.api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
-                },
-            });
-
-            // Initialize AUTHFAIL plugin
-            converse.plugins.add('conversejs-sib-disconnected', {
-                initialize() {
-                    this._converse.api.listen.on('disconnected', () => {
-                        if (this._converse.connfeedback.attributes.connection_status === converse.env.Strophe.Status.AUTHFAIL) {
-                            Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
-                                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`,
-                            );
-                        } else {
-                            Array.from(document.querySelectorAll('solid-xmpp-chat')).map(el => el.shadowRoot.innerHTML =
-                                `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${this._converse.connfeedback.attributes.message}</i></div>`,
-                            );
-                        }
-                    });
-                },
-            });
 
             // Initialize deferred resolution plugin
-            converse.plugins.add('conversejs-sib-focused', {
+            converse.plugins.add('sib-connected', {
                 initialize() {
-                    this._converse.api.listen.on('chatBoxFocused', function() {
-                        // Get the currently used solid-xmpp-chat & send read event of
-                        const resource = Array.from(document.querySelectorAll('solid-xmpp-chat'))
-                            .filter(el => {
-                                return el.shadowRoot.getElementById('conversejs');
-                            })
-                            .pop()
-                            .component.resource;
-                        window.dispatchEvent(new CustomEvent('read', {
-                            detail: {
-                                resource: resource,
-                            },
-                        }));
-                    });
+                    const { api } = this._converse;
+                    api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
                 },
             });
 
@@ -290,10 +235,10 @@ export const SolidXMPPChat = {
                 },
                 'whitelisted_plugins': [
                     'converse-rai',
-                    'conversejs-sib-disconnected',
-                    'conversejs-sib-connected',
-                    'conversejs-sib-focused',
-                    'conversejs-changechat',
+                    'sib-connected',
+                    'sib-disconnected',
+                    'sib-focused',
+                    'sib-change-chat',
                     'sib-subscribe-to-rai',
                     'sib-custom-hats',
                     'sib-remove-notifications',
-- 
GitLab


From 4af2332c7c40b0c005660d252b18076858cf61b2 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:32:48 +0100
Subject: [PATCH 06/12] import missing store

---
 src/plugins/sib-subscribe-to-rai.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/plugins/sib-subscribe-to-rai.js b/src/plugins/sib-subscribe-to-rai.js
index fee52f6..634c487 100644
--- a/src/plugins/sib-subscribe-to-rai.js
+++ b/src/plugins/sib-subscribe-to-rai.js
@@ -1,3 +1,5 @@
+import { store } from 'https://cdn.skypack.dev/@startinblox/core@0.15';
+
 /**
  * Initialize rai plugin.
  */
-- 
GitLab


From 261b0cde7e16c71d9aed61250bd088569ce099c2 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:39:16 +0100
Subject: [PATCH 07/12] merge sib-focused plugin into the sib-chat-nav

---
 ...-change-chat.js => sib-chat-navigation.js} | 22 ++++++++++++++++---
 src/plugins/sib-focused.js                    | 21 ------------------
 src/solid-xmpp-chat.js                        |  6 ++---
 3 files changed, 21 insertions(+), 28 deletions(-)
 rename src/plugins/{sib-change-chat.js => sib-chat-navigation.js} (58%)
 delete mode 100644 src/plugins/sib-focused.js

diff --git a/src/plugins/sib-change-chat.js b/src/plugins/sib-chat-navigation.js
similarity index 58%
rename from src/plugins/sib-change-chat.js
rename to src/plugins/sib-chat-navigation.js
index 7a3363a..0679177 100644
--- a/src/plugins/sib-change-chat.js
+++ b/src/plugins/sib-chat-navigation.js
@@ -2,7 +2,7 @@
  * Register a new event to move the converse element
  * into another component.
  */
-converse.plugins.add('sib-change-chat', {
+converse.plugins.add('sib-chat-navigation', {
     initialize() {
         const _converse = this._converse;
         const { api } = _converse;
@@ -17,7 +17,7 @@ converse.plugins.add('sib-change-chat', {
             jid = jid.toLowerCase();
             _converse.root = root;
 
-            // Get the current used solid-xmpp-chat
+            // Find the converse root
             const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
                 .map(el => el.shadowRoot.getElementById('conversejs'))
                 .filter(el => el)
@@ -33,5 +33,21 @@ converse.plugins.add('sib-change-chat', {
                 await api.chats.open(jid, {}, true);
             }
         });
+
+        // Get the currently used solid-xmpp-chat
+        const getCurrentChat = () => Array.from(document.querySelectorAll('solid-xmpp-chat'))
+            .filter(el => el.shadowRoot.getElementById('conversejs'))
+            .pop();
+
+        // When the a chat box is focused, send the read event
+        api.listen.on('chatBoxFocused', function() {
+            const resource = getCurrentChat()?.component.resource;
+
+            window.dispatchEvent(new CustomEvent('read', {
+                detail: {
+                    resource,
+                },
+            }));
+        });
     },
-});
\ No newline at end of file
+});
diff --git a/src/plugins/sib-focused.js b/src/plugins/sib-focused.js
deleted file mode 100644
index fb7de32..0000000
--- a/src/plugins/sib-focused.js
+++ /dev/null
@@ -1,21 +0,0 @@
-converse.plugins.add('sib-focused', {
-    initialize() {
-        const _converse = this._converse;
-        const { api } = _converse;
-
-        // Get the currently used solid-xmpp-chat
-        const getCurrentChat = () => Array.from(document.querySelectorAll('solid-xmpp-chat'))
-            .filter(el => el.shadowRoot.getElementById('conversejs'))
-            .pop();
-
-        api.listen.on('chatBoxFocused', function() {
-            const resource = getCurrentChat()?.component.resource;
-
-            window.dispatchEvent(new CustomEvent('read', {
-                detail: {
-                    resource,
-                },
-            }));
-        });
-    },
-});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index acbebbc..050a0d8 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -6,10 +6,9 @@ import './conversejs/converse.min.js';
 import './conversejs/emojis.js';
 
 import './plugins/converse-rai.js';
-import './plugins/sib-change-chat.js';
+import './plugins/sib-chat-navigation.js';
 import './plugins/sib-custom-hats.js';
 import './plugins/sib-disconnected.js';
-import './plugins/sib-focused.js';
 import './plugins/sib-remove-notifications.js';
 import './plugins/sib-subscribe-to-rai.js';
 
@@ -237,8 +236,7 @@ export const SolidXMPPChat = {
                     'converse-rai',
                     'sib-connected',
                     'sib-disconnected',
-                    'sib-focused',
-                    'sib-change-chat',
+                    'sib-chat-navigation',
                     'sib-subscribe-to-rai',
                     'sib-custom-hats',
                     'sib-remove-notifications',
-- 
GitLab


From fa903e2df7716240fb64a094d67f4df1701d5f9c Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:43:54 +0100
Subject: [PATCH 08/12] bind deferred promise to a real function

---
 src/utils.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/utils.js b/src/utils.js
index 68e3bce..0275089 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,9 +1,9 @@
 export class Deferred {
     constructor() {
-        this.promise = new Promise(((resolve, reject) => {
+        this.promise = new Promise(function(resolve, reject) {
             this.resolve = resolve;
             this.reject = reject;
-        }).bind(this));
+        }.bind(this));
         this.then = this.promise.then.bind(this.promise);
         this.catch = this.promise.catch.bind(this.promise);
     }
-- 
GitLab


From 44d099006cd844bc8934bbfb115f2c26197a3087 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:58:03 +0100
Subject: [PATCH 09/12] remove unused code

---
 src/solid-xmpp-chat.js | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 050a0d8..25bd0be 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -45,12 +45,10 @@ export const SolidXMPPChat = {
     async created() {
         const check_identified = await document.querySelector('sib-auth').getUserIdToken();
         if (check_identified) {
-            this.element.attachShadow({
-                mode: 'open',
-            });
+            this.element.attachShadow({ mode: 'open' });
             this.importCSS(`${ComponentPath}/dist/conversejs/converse.min.css?min`);
             this.importCSS(`${ComponentPath}/dist/index.css?min`);
-            if (window.converse_sib === undefined) {
+            if (typeof converse_sib === 'undefined') {
                 this.initializeConverse();
             }
         } // Else, not logged in on page load (even if not on chat)
@@ -143,22 +141,8 @@ export const SolidXMPPChat = {
         // Deferred resolved after converse.initialize
         converse_sib.connected_deferred = new Deferred();
 
-        // Registering window.converse_sib.service
-        converse_sib.service = {
-            'waitUntilLoaded': converse_sib.loaded_deferred.promise,
-            'initialize': function(options) {
-                this.waitUntilLoaded().done(this.api.initialize, options);
-            },
-            'waitUntilConnected': converse_sib.connected_deferred.promise,
-            'plugins': {},
-        };
-
         this.removeConverseDatabase();
 
-        // Alias for solid-xmpp-chat use # want to un-expose converse from window later
-        // window.converse_sib.service.api === window.converse
-        converse_sib.service.api = converse;
-
         // Initialize deferred resolution plugin
         setTimeout(async () => {
 
-- 
GitLab


From 441696e14529310aa68900fe2298a4e34c362a83 Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 15:58:53 +0100
Subject: [PATCH 10/12] reorder plugins

---
 src/solid-xmpp-chat.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 25bd0be..5ea8acd 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -218,12 +218,12 @@ export const SolidXMPPChat = {
                 },
                 'whitelisted_plugins': [
                     'converse-rai',
-                    'sib-connected',
-                    'sib-disconnected',
                     'sib-chat-navigation',
-                    'sib-subscribe-to-rai',
+                    'sib-connected',
                     'sib-custom-hats',
+                    'sib-disconnected',
                     'sib-remove-notifications',
+                    'sib-subscribe-to-rai',
                 ],
             });
 
-- 
GitLab


From 1cb3f6c9b8ab02cbbb10dc67b7ffec1f0fbcaf3a Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 18:12:17 +0100
Subject: [PATCH 11/12] remove prettier from project (user pref)

---
 .gitignore        | 3 ++-
 .prettierrc       | 8 --------
 package-lock.json | 6 ------
 package.json      | 1 -
 4 files changed, 2 insertions(+), 16 deletions(-)
 delete mode 100644 .prettierrc

diff --git a/.gitignore b/.gitignore
index 44937af..a187b43 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 node_modules/*
 stamp-npm
-dist
\ No newline at end of file
+dist
+/.prettierrc
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index f272a0a..0000000
--- a/.prettierrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "arrowParens": "avoid",
-    "trailingComma": "es5",
-    "tabWidth": 4,
-    "singleQuote": true,
-    "quoteProps": "preserve",
-    "printWidth": 120
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 3134d39..ba4b4f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1864,12 +1864,6 @@
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
       "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
     },
-    "prettier": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
-      "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
-      "dev": true
-    },
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
diff --git a/package.json b/package.json
index 2185785..b0e3bfa 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,6 @@
     "sass": "^1.32.5"
   },
   "devDependencies": {
-    "prettier": "^2.2.1",
     "watch-cli": "^0.2.3"
   },
   "scripts": {
-- 
GitLab


From 9fb243e9d715c0177baa2a0deb5ac6adbe9e70bf Mon Sep 17 00:00:00 2001
From: ubermanu <e.vodor@gmail.com>
Date: Wed, 10 Mar 2021 18:36:11 +0100
Subject: [PATCH 12/12] format code with 2 spaces as indent size

---
 build-scss.js                           |  20 +-
 src/plugins/converse-rai.js             | 354 ++++++++++----------
 src/plugins/sib-chat-navigation.js      |  94 +++---
 src/plugins/sib-custom-hats.js          |  34 +-
 src/plugins/sib-disconnected.js         |  34 +-
 src/plugins/sib-mam-history.js          |  70 ++--
 src/plugins/sib-remove-notifications.js |  38 +--
 src/plugins/sib-subscribe-to-rai.js     | 116 +++----
 src/solid-xmpp-chat.js                  | 418 ++++++++++++------------
 src/utils.js                            |  16 +-
 10 files changed, 597 insertions(+), 597 deletions(-)

diff --git a/build-scss.js b/build-scss.js
index ea8fa43..9e52edc 100644
--- a/build-scss.js
+++ b/build-scss.js
@@ -3,16 +3,16 @@ const sass = require('sass');
 const fs = require('fs');
 
 sass.render({
-    file: 'src/styles/index.scss',
-    outFile: 'dist/index.css',
+  file: 'src/styles/index.scss',
+  outFile: 'dist/index.css',
 }, function(error, result) {
-    if (!error) {
-        if (!fs.existsSync('dist')) {
-            fs.mkdirSync('dist', { recursive: true });
-        }
-        fs.writeFile('dist/index.css', String(result.css).replace(/\/lib\/solid-xmpp-chat/g, path), (e) => {
-        });
-    } else {
-        console.error(error);
+  if (!error) {
+    if (!fs.existsSync('dist')) {
+      fs.mkdirSync('dist', { recursive: true });
     }
+    fs.writeFile('dist/index.css', String(result.css).replace(/\/lib\/solid-xmpp-chat/g, path), (e) => {
+    });
+  } else {
+    console.error(error);
+  }
 });
diff --git a/src/plugins/converse-rai.js b/src/plugins/converse-rai.js
index 24ed1ad..c110906 100644
--- a/src/plugins/converse-rai.js
+++ b/src/plugins/converse-rai.js
@@ -1,195 +1,195 @@
 (function() {
-    let Strophe, $iq, $msg, $pres, $build, b64_sha1, _, Backbone, dayjs, _converse;
-    let interestingServers = new Set();
-    let subscribedServers = new Set();
-
-    converse.plugins.add('converse-rai', {
-        'dependencies': [],
-
-        'initialize': function() {
-            _converse = this._converse;
-
-            Strophe = converse.env.Strophe;
-            $iq = converse.env.$iq;
-            $msg = converse.env.$msg;
-            $pres = converse.env.$pres;
-            $build = converse.env.$build;
-            b64_sha1 = converse.env.b64_sha1;
-            _ = converse.env._;
-            Backbone = converse.env.Backbone;
-            dayjs = converse.env.dayjs;
-
-            _converse.api.settings.extend({
-                rai_notification: true,
-                rai_notification_label: 'Room Activity Indicator',
-            });
-
-            _converse.api.listen.on('connected', function() {
-                setupRoomActivityIndicators();
-            });
-
-            _converse.api.listen.on('chatRoomViewInitialized', function(view) {
-                const jid = view.model.get('jid');
-
-                if (view.model.get('num_unread') > 0 || view.model.get('num_unread_general') > 0) {
-                    emitNotification(jid);
-                }
-            });
-
-            _converse.api.listen.on('raiRoomsUpdated', function(rooms) {
-                interestingServers = new Set(rooms.filter(room => room).map(Strophe.getDomainFromJid));
-                if (_converse.api.connection.connected()) {
-                    updateSubscriptions();
-                }
-            });
-
-            _converse.api.listen.on('chatBoxScrolledDown', function(view) {
-                const jid = view.chatbox.get('jid');
-                const id_attr = 'stanza_id ' + jid;
-                const messages = view.chatbox.messages;
-
-                if (!getUnreadStatus(jid)) {
-                    return;
-                }
-
-                for (let i = messages.length - 1; i >= 0; i--) {
-                    const message = messages.at(i);
-
-                    if (message.has(id_attr)) {
-                        let id = message.get(id_attr);
-                        if (id != sessionStorage.getItem('rai_displayed.' + jid)) {
-                            sessionStorage.setItem('rai_displayed.' + jid, id);
-                            setUnreadStatus(jid, false);
-                            setTimeout(() => sendMarker(jid, id, 'displayed'), 0);
-                        }
-                        break;
-                    }
-                }
-            });
-
-            _converse.api.listen.on('chatBoxInsertedIntoDOM', function(view) {
-                const jid = view.model.get('jid');
-
-                if (view.model.get('num_unread') > 0) {
-                    emitNotification(jid);
-                }
-
-            });
-
-            _converse.api.listen.on('message', function(data) {
-                var chatbox = data.chatbox;
-                var history = data.attrs.is_archived;
-                var sender = data.attrs.sender;
-                var body = data.attrs.body;
-
-                if (!history && body && chatbox && sender !== 'me') {
-                    const alert = chatbox.get('num_unread') > 0;
-                    const notify = chatbox.get('num_unread_general') > 0;
-
-                    if (alert || notify) {
-                        emitNotification(chatbox.get('jid'), alert);
-                    }
-                }
-            });
-        },
-    });
-
+  let Strophe, $iq, $msg, $pres, $build, b64_sha1, _, Backbone, dayjs, _converse;
+  let interestingServers = new Set();
+  let subscribedServers = new Set();
+
+  converse.plugins.add('converse-rai', {
+    'dependencies': [],
+
+    'initialize': function() {
+      _converse = this._converse;
+
+      Strophe = converse.env.Strophe;
+      $iq = converse.env.$iq;
+      $msg = converse.env.$msg;
+      $pres = converse.env.$pres;
+      $build = converse.env.$build;
+      b64_sha1 = converse.env.b64_sha1;
+      _ = converse.env._;
+      Backbone = converse.env.Backbone;
+      dayjs = converse.env.dayjs;
+
+      _converse.api.settings.extend({
+        rai_notification: true,
+        rai_notification_label: 'Room Activity Indicator',
+      });
+
+      _converse.api.listen.on('connected', function() {
+        setupRoomActivityIndicators();
+      });
+
+      _converse.api.listen.on('chatRoomViewInitialized', function(view) {
+        const jid = view.model.get('jid');
+
+        if (view.model.get('num_unread') > 0 || view.model.get('num_unread_general') > 0) {
+          emitNotification(jid);
+        }
+      });
 
-    function subscribeServer(server_name) {
-        const id = Math.random().toString(36).substr(2, 9);
-        _converse.connection.send(converse.env.$pres({
-            to: server_name,
-            id: id,
-        }).c('rai', {
-            'xmlns': 'xmpp:prosody.im/protocol/rai',
-        }));
-    }
+      _converse.api.listen.on('raiRoomsUpdated', function(rooms) {
+        interestingServers = new Set(rooms.filter(room => room).map(Strophe.getDomainFromJid));
+        if (_converse.api.connection.connected()) {
+          updateSubscriptions();
+        }
+      });
 
-    function unsubscribeServer(server_name) {
-        _converse.connection.send(converse.env.$pres({
-            to: server_name, type: 'unavailable',
-        }).c('rai', {
-            'xmlns': 'xmpp:prosody.im/protocol/rai',
-        }));
-    }
+      _converse.api.listen.on('chatBoxScrolledDown', function(view) {
+        const jid = view.chatbox.get('jid');
+        const id_attr = 'stanza_id ' + jid;
+        const messages = view.chatbox.messages;
 
-    function updateSubscriptions() {
-        var new_servers = new Set([...interestingServers].filter(server => !subscribedServers.has(server)));
-        var obsolete_servers = new Set([...subscribedServers].filter(server => !interestingServers.has(server)));
-        for (let server of obsolete_servers) {
-            unsubscribeServer(server);
+        if (!getUnreadStatus(jid)) {
+          return;
         }
-        for (let server of new_servers) {
-            subscribeServer(server);
-        }
-    }
 
-    function setupRoomActivityIndicators() {
-        updateSubscriptions();
-        // If we already have unread notifications stored for this session, emit them now
-        for (var i = 0; i < sessionStorage.length; i++) {
-            if (sessionStorage.key(i).indexOf('rai_notify.') == 0) {
-                const jid = sessionStorage.key(i).substring(11);
-                emitNotification(jid);
+        for (let i = messages.length - 1; i >= 0; i--) {
+          const message = messages.at(i);
+
+          if (message.has(id_attr)) {
+            let id = message.get(id_attr);
+            if (id != sessionStorage.getItem('rai_displayed.' + jid)) {
+              sessionStorage.setItem('rai_displayed.' + jid, id);
+              setUnreadStatus(jid, false);
+              setTimeout(() => sendMarker(jid, id, 'displayed'), 0);
             }
+            break;
+          }
         }
+      });
 
-        // Listen for incoming RAI from the server
-        _converse.connection.addHandler(function(message) {
-            const from_jid = message.attributes.from?.nodevalue;
-            const room_jid = from_jid?.split('/')[0];
-            const room = '';
-            let ignore = false;
-            for (let i = 0; i < _converse.chatboxes.models.length; i++) {
-                if (_converse.chatboxes.models[i].id === room_jid) {
-                    room = _converse.chatboxes.models[i].id;
-                    break;
-                }
-            }
-            if (room && from_jid && room_jid) {
-                if (from_jid === room_jid + '/' + room.get('nick')) {
-                    ignore = true;
-                }
-            }
-            if (message && !ignore)
-                message.querySelectorAll('activity').forEach(function(activity) {
-                    if (activity && activity.namespaceURI == 'xmpp:prosody.im/protocol/rai') {
-                        const jid = activity.textContent;
-                        setUnreadStatus(jid, true);
-                        emitNotification(jid);
-                    }
-                });
-            return true;
-        }, null, 'message');
-    }
+      _converse.api.listen.on('chatBoxInsertedIntoDOM', function(view) {
+        const jid = view.model.get('jid');
 
-    function setUnreadStatus(jid, flag) {
-        if (flag) {
-            sessionStorage.setItem('rai_notify.' + jid, 'true');
-        } else {
-            sessionStorage.removeItem('rai_notify.' + jid);
+        if (view.model.get('num_unread') > 0) {
+          emitNotification(jid);
         }
-    }
 
-    function getUnreadStatus(jid) {
-        return sessionStorage.getItem('rai_notify.' + jid) == 'true';
-    }
+      });
+
+      _converse.api.listen.on('message', function(data) {
+        var chatbox = data.chatbox;
+        var history = data.attrs.is_archived;
+        var sender = data.attrs.sender;
+        var body = data.attrs.body;
 
-    function emitNotification(jid, alert) {
-        _converse.api.trigger('chatRoomActivityIndicators', jid);
+        if (!history && body && chatbox && sender !== 'me') {
+          const alert = chatbox.get('num_unread') > 0;
+          const notify = chatbox.get('num_unread_general') > 0;
+
+          if (alert || notify) {
+            emitNotification(chatbox.get('jid'), alert);
+          }
+        }
+      });
+    },
+  });
+
+
+  function subscribeServer(server_name) {
+    const id = Math.random().toString(36).substr(2, 9);
+    _converse.connection.send(converse.env.$pres({
+      to: server_name,
+      id: id,
+    }).c('rai', {
+      'xmlns': 'xmpp:prosody.im/protocol/rai',
+    }));
+  }
+
+  function unsubscribeServer(server_name) {
+    _converse.connection.send(converse.env.$pres({
+      to: server_name, type: 'unavailable',
+    }).c('rai', {
+      'xmlns': 'xmpp:prosody.im/protocol/rai',
+    }));
+  }
+
+  function updateSubscriptions() {
+    var new_servers = new Set([...interestingServers].filter(server => !subscribedServers.has(server)));
+    var obsolete_servers = new Set([...subscribedServers].filter(server => !interestingServers.has(server)));
+    for (let server of obsolete_servers) {
+      unsubscribeServer(server);
+    }
+    for (let server of new_servers) {
+      subscribeServer(server);
+    }
+  }
+
+  function setupRoomActivityIndicators() {
+    updateSubscriptions();
+    // If we already have unread notifications stored for this session, emit them now
+    for (var i = 0; i < sessionStorage.length; i++) {
+      if (sessionStorage.key(i).indexOf('rai_notify.') == 0) {
+        const jid = sessionStorage.key(i).substring(11);
+        emitNotification(jid);
+      }
     }
 
-    function sendMarker(to_jid, id, type) {
-        const stanza = converse.env.$msg({
-            'from': _converse.connection.jid,
-            'id': Math.random().toString(36).substr(2, 9),
-            'to': to_jid,
-            'type': 'groupchat',
-        }).c(type, {
-            'xmlns': converse.env.Strophe.NS.MARKERS,
-            'id': id,
+    // Listen for incoming RAI from the server
+    _converse.connection.addHandler(function(message) {
+      const from_jid = message.attributes.from?.nodevalue;
+      const room_jid = from_jid?.split('/')[0];
+      const room = '';
+      let ignore = false;
+      for (let i = 0; i < _converse.chatboxes.models.length; i++) {
+        if (_converse.chatboxes.models[i].id === room_jid) {
+          room = _converse.chatboxes.models[i].id;
+          break;
+        }
+      }
+      if (room && from_jid && room_jid) {
+        if (from_jid === room_jid + '/' + room.get('nick')) {
+          ignore = true;
+        }
+      }
+      if (message && !ignore)
+        message.querySelectorAll('activity').forEach(function(activity) {
+          if (activity && activity.namespaceURI == 'xmpp:prosody.im/protocol/rai') {
+            const jid = activity.textContent;
+            setUnreadStatus(jid, true);
+            emitNotification(jid);
+          }
         });
-
-        _converse.api.send(stanza);
+      return true;
+    }, null, 'message');
+  }
+
+  function setUnreadStatus(jid, flag) {
+    if (flag) {
+      sessionStorage.setItem('rai_notify.' + jid, 'true');
+    } else {
+      sessionStorage.removeItem('rai_notify.' + jid);
     }
+  }
+
+  function getUnreadStatus(jid) {
+    return sessionStorage.getItem('rai_notify.' + jid) == 'true';
+  }
+
+  function emitNotification(jid, alert) {
+    _converse.api.trigger('chatRoomActivityIndicators', jid);
+  }
+
+  function sendMarker(to_jid, id, type) {
+    const stanza = converse.env.$msg({
+      'from': _converse.connection.jid,
+      'id': Math.random().toString(36).substr(2, 9),
+      'to': to_jid,
+      'type': 'groupchat',
+    }).c(type, {
+      'xmlns': converse.env.Strophe.NS.MARKERS,
+      'id': id,
+    });
+
+    _converse.api.send(stanza);
+  }
 })();
diff --git a/src/plugins/sib-chat-navigation.js b/src/plugins/sib-chat-navigation.js
index 0679177..230cfcf 100644
--- a/src/plugins/sib-chat-navigation.js
+++ b/src/plugins/sib-chat-navigation.js
@@ -3,51 +3,51 @@
  * into another component.
  */
 converse.plugins.add('sib-chat-navigation', {
-    initialize() {
-        const _converse = this._converse;
-        const { api } = _converse;
-
-        window.addEventListener('sib-change-chat', async ev => {
-            let { jid, is_groupchat, root } = ev.detail;
-
-            if (!jid) {
-                return;
-            }
-
-            jid = jid.toLowerCase();
-            _converse.root = root;
-
-            // Find the converse root
-            const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
-                .map(el => el.shadowRoot.getElementById('conversejs'))
-                .filter(el => el)
-                .pop();
-
-            if (converse_el) {
-                root.appendChild(converse_el);
-            }
-
-            if (is_groupchat) {
-                await api.rooms.open(jid, {}, true);
-            } else {
-                await api.chats.open(jid, {}, true);
-            }
-        });
-
-        // Get the currently used solid-xmpp-chat
-        const getCurrentChat = () => Array.from(document.querySelectorAll('solid-xmpp-chat'))
-            .filter(el => el.shadowRoot.getElementById('conversejs'))
-            .pop();
-
-        // When the a chat box is focused, send the read event
-        api.listen.on('chatBoxFocused', function() {
-            const resource = getCurrentChat()?.component.resource;
-
-            window.dispatchEvent(new CustomEvent('read', {
-                detail: {
-                    resource,
-                },
-            }));
-        });
-    },
+  initialize() {
+    const _converse = this._converse;
+    const { api } = _converse;
+
+    window.addEventListener('sib-change-chat', async ev => {
+      let { jid, is_groupchat, root } = ev.detail;
+
+      if (!jid) {
+        return;
+      }
+
+      jid = jid.toLowerCase();
+      _converse.root = root;
+
+      // Find the converse root
+      const converse_el = Array.from(document.querySelectorAll('solid-xmpp-chat'))
+        .map(el => el.shadowRoot.getElementById('conversejs'))
+        .filter(el => el)
+        .pop();
+
+      if (converse_el) {
+        root.appendChild(converse_el);
+      }
+
+      if (is_groupchat) {
+        await api.rooms.open(jid, {}, true);
+      } else {
+        await api.chats.open(jid, {}, true);
+      }
+    });
+
+    // Get the currently used solid-xmpp-chat
+    const getCurrentChat = () => Array.from(document.querySelectorAll('solid-xmpp-chat'))
+      .filter(el => el.shadowRoot.getElementById('conversejs'))
+      .pop();
+
+    // When the a chat box is focused, send the read event
+    api.listen.on('chatBoxFocused', function() {
+      const resource = getCurrentChat()?.component.resource;
+
+      window.dispatchEvent(new CustomEvent('read', {
+        detail: {
+          resource,
+        },
+      }));
+    });
+  },
 });
diff --git a/src/plugins/sib-custom-hats.js b/src/plugins/sib-custom-hats.js
index 334097d..f7b7871 100644
--- a/src/plugins/sib-custom-hats.js
+++ b/src/plugins/sib-custom-hats.js
@@ -2,22 +2,22 @@
  * Transform hats to custom values.
  */
 converse.plugins.add('sib-custom-hats', {
-    overrides: {
-        getHats: function() {
-            const hat_conversions = { 'admin': 'Administrateur' };
-            const hats = this.__super__.getHats.apply(this, arguments);
-            if (!hat_conversions) {
-                return hats;
-            } else {
-                const role_affiliations = Object.keys(hat_conversions);
-                return hats.map((hat) => {
-                    if (role_affiliations.includes(hat.title)) {
-                        return ({ title: hat_conversions[hat.title] });
-                    } else {
-                        return hat;
-                    }
-                });
-            }
-        },
+  overrides: {
+    getHats: function() {
+      const hat_conversions = { 'admin': 'Administrateur' };
+      const hats = this.__super__.getHats.apply(this, arguments);
+      if (!hat_conversions) {
+        return hats;
+      } else {
+        const role_affiliations = Object.keys(hat_conversions);
+        return hats.map((hat) => {
+          if (role_affiliations.includes(hat.title)) {
+            return ({ title: hat_conversions[hat.title] });
+          } else {
+            return hat;
+          }
+        });
+      }
     },
+  },
 });
diff --git a/src/plugins/sib-disconnected.js b/src/plugins/sib-disconnected.js
index 8cb6dfe..3de3d30 100644
--- a/src/plugins/sib-disconnected.js
+++ b/src/plugins/sib-disconnected.js
@@ -2,23 +2,23 @@
  * Initialize AUTHFAIL plugin
  */
 converse.plugins.add('sib-disconnected', {
-    initialize() {
-        const _converse = this._converse;
-        const { api } = _converse;
-        const { Strophe } = converse.env;
+  initialize() {
+    const _converse = this._converse;
+    const { api } = _converse;
+    const { Strophe } = converse.env;
 
-        const getChats = () => Array.from(document.querySelectorAll('solid-xmpp-chat'));
+    const getChats = () => Array.from(document.querySelectorAll('solid-xmpp-chat'));
 
-        api.listen.on('disconnected', () => {
-            if (_converse.connfeedback.attributes.connection_status === Strophe.Status.AUTHFAIL) {
-                getChats().map(el => el.shadowRoot.innerHTML =
-                    `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`,
-                );
-            } else {
-                getChats().map(el => el.shadowRoot.innerHTML =
-                    `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${_converse.connfeedback.attributes.message}</i></div>`,
-                );
-            }
-        });
-    },
+    api.listen.on('disconnected', () => {
+      if (_converse.connfeedback.attributes.connection_status === Strophe.Status.AUTHFAIL) {
+        getChats().map(el => el.shadowRoot.innerHTML =
+          `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur d'authentification.</b><br /><i style='color:grey;'>Êtes-vous sur le Hubl affilié à votre compte ?</i></div>`,
+        );
+      } else {
+        getChats().map(el => el.shadowRoot.innerHTML =
+          `<div style='margin:3em;line-height:32px;'><b style='color:red;'>Erreur.</b><br /><i style='color:grey;'>${_converse.connfeedback.attributes.message}</i></div>`,
+        );
+      }
+    });
+  },
 });
diff --git a/src/plugins/sib-mam-history.js b/src/plugins/sib-mam-history.js
index bffcc14..f0704e7 100644
--- a/src/plugins/sib-mam-history.js
+++ b/src/plugins/sib-mam-history.js
@@ -3,46 +3,46 @@
  * from the setting `archived_messages_page_size`.
  */
 converse.plugins.add('sib-mam-history', {
-    dependencies: [
-        'converse-mam',
-    ],
-    initialize() {
-        const { api } = this._converse;
-        let counter = 0;
+  dependencies: [
+    'converse-mam',
+  ],
+  initialize() {
+    const { api } = this._converse;
+    let counter = 0;
 
-        api.listen.on('MAMResult', async data => {
+    api.listen.on('MAMResult', async data => {
 
-            const max = +api.settings.get('archived_messages_page_size');
-            const messages = await Promise.all(data.messages);
+      const max = +api.settings.get('archived_messages_page_size');
+      const messages = await Promise.all(data.messages);
 
-            // Increase counter with the messages that contains a body
-            counter += messages.filter(attrs => attrs.body).length;
+      // Increase counter with the messages that contains a body
+      counter += messages.filter(attrs => attrs.body).length;
 
-            // Stop if the max value is not specified
-            // Stop if there are less messages available than the page size
-            // Stop if the counter registers more messages than the max value
-            if (!max || messages.length < max || counter >= max) {
-                counter = 0;
-                return;
-            }
+      // Stop if the max value is not specified
+      // Stop if there are less messages available than the page size
+      // Stop if the counter registers more messages than the max value
+      if (!max || messages.length < max || counter >= max) {
+        counter = 0;
+        return;
+      }
 
-            const is_groupchat = data.chatbox.get('type') === converse.CHATROOMS_TYPE;
-            const oldest_message = messages.pop();
+      const is_groupchat = data.chatbox.get('type') === converse.CHATROOMS_TYPE;
+      const oldest_message = messages.pop();
 
-            if (oldest_message) {
-                const by_jid = is_groupchat ? data.chatbox.get('jid') : converse.bare_jid;
-                const stanza_id = oldest_message && oldest_message['stanza_id '.concat(by_jid)];
+      if (oldest_message) {
+        const by_jid = is_groupchat ? data.chatbox.get('jid') : converse.bare_jid;
+        const stanza_id = oldest_message && oldest_message['stanza_id '.concat(by_jid)];
 
-                if (stanza_id) {
-                    await data.chatbox.fetchArchivedMessages({
-                        'before': stanza_id
-                    });
-                } else {
-                    await data.chatbox.fetchArchivedMessages({
-                        'end': oldest_message['time']
-                    });
-                }
-            }
-        })
-    }
+        if (stanza_id) {
+          await data.chatbox.fetchArchivedMessages({
+            'before': stanza_id,
+          });
+        } else {
+          await data.chatbox.fetchArchivedMessages({
+            'end': oldest_message['time'],
+          });
+        }
+      }
+    });
+  },
 });
diff --git a/src/plugins/sib-remove-notifications.js b/src/plugins/sib-remove-notifications.js
index dd11271..b80d748 100644
--- a/src/plugins/sib-remove-notifications.js
+++ b/src/plugins/sib-remove-notifications.js
@@ -3,24 +3,24 @@
  * so that permission request for notifications don't happen.
  */
 converse.plugins.add('sib-remove-notifications', {
-    overrides: {
-        requestPermission: function() {
-        },
-        showMessageNotification: function() {
-        },
-        showChatStateNotification: function() {
-        },
-        showContactRequestNotification: function() {
-        },
-        showFeedbackNotification: function() {
-        },
-        handleChatStateNotification: function() {
-        },
-        handleMessageNotification: function() {
-        },
-        handleContactRequestNotification: function() {
-        },
-        handleFeedback: function() {
-        },
+  overrides: {
+    requestPermission: function() {
     },
+    showMessageNotification: function() {
+    },
+    showChatStateNotification: function() {
+    },
+    showContactRequestNotification: function() {
+    },
+    showFeedbackNotification: function() {
+    },
+    handleChatStateNotification: function() {
+    },
+    handleMessageNotification: function() {
+    },
+    handleContactRequestNotification: function() {
+    },
+    handleFeedback: function() {
+    },
+  },
 });
diff --git a/src/plugins/sib-subscribe-to-rai.js b/src/plugins/sib-subscribe-to-rai.js
index 634c487..51dbb91 100644
--- a/src/plugins/sib-subscribe-to-rai.js
+++ b/src/plugins/sib-subscribe-to-rai.js
@@ -4,67 +4,67 @@ import { store } from 'https://cdn.skypack.dev/@startinblox/core@0.15';
  * Initialize rai plugin.
  */
 converse.plugins.add('sib-subscribe-to-rai', {
-    dependencies: [
-        'converse-rai',
-    ],
-    async initialize() {
-        const _converse = this._converse;
-        const { api } = _converse;
+  dependencies: [
+    'converse-rai',
+  ],
+  async initialize() {
+    const _converse = this._converse;
+    const { api } = _converse;
 
-        const getCircles = new Promise((resolve, reject) => {
-            const circleInterval = setInterval(async () => {
-                let retry = false;
-                let circles = [];
-                const user = await document.querySelector('sib-auth').getUser();
-                const userProfile = await store.getData(user['@id'], this.context);
-                for (let circleMembership of await userProfile['circles.ldp:contains']) {
-                    if (circleMembership) {
-                        circles.push(await circleMembership['circle.jabberID']);
-                    } else {
-                        retry = true;
-                    }
-                }
-                if (!retry) {
-                    clearInterval(circleInterval);
-                    resolve(circles);
-                }
-            }, 250);
-        });
+    const getCircles = new Promise((resolve, reject) => {
+      const circleInterval = setInterval(async () => {
+        let retry = false;
+        let circles = [];
+        const user = await document.querySelector('sib-auth').getUser();
+        const userProfile = await store.getData(user['@id'], this.context);
+        for (let circleMembership of await userProfile['circles.ldp:contains']) {
+          if (circleMembership) {
+            circles.push(await circleMembership['circle.jabberID']);
+          } else {
+            retry = true;
+          }
+        }
+        if (!retry) {
+          clearInterval(circleInterval);
+          resolve(circles);
+        }
+      }, 250);
+    });
 
-        const getProjects = new Promise((resolve, reject) => {
-            const projectInterval = setInterval(async () => {
-                let retry = false;
-                let projects = [];
-                const user = await document.querySelector('sib-auth').getUser();
-                const userProfile = await store.getData(user['@id'], this.context);
-                for (let projectMembership of await userProfile['projects.ldp:contains']) {
-                    if (projectMembership) {
-                        projects.push(await projectMembership['project.jabberID']);
-                    } else {
-                        retry = true;
-                    }
-                }
-                if (!retry) {
-                    clearInterval(projectInterval);
-                    resolve(projects);
-                }
-            }, 250);
-        });
+    const getProjects = new Promise((resolve, reject) => {
+      const projectInterval = setInterval(async () => {
+        let retry = false;
+        let projects = [];
+        const user = await document.querySelector('sib-auth').getUser();
+        const userProfile = await store.getData(user['@id'], this.context);
+        for (let projectMembership of await userProfile['projects.ldp:contains']) {
+          if (projectMembership) {
+            projects.push(await projectMembership['project.jabberID']);
+          } else {
+            retry = true;
+          }
+        }
+        if (!retry) {
+          clearInterval(projectInterval);
+          resolve(projects);
+        }
+      }, 250);
+    });
 
-        let userRooms = (await Promise.all([
-            getCircles,
-            getProjects,
-        ])).flat();
+    let userRooms = (await Promise.all([
+      getCircles,
+      getProjects,
+    ])).flat();
 
-        // @MattJ Here userRooms is an array of each jabberID the user is on.
-        api.trigger('raiRoomsUpdated', userRooms);
+    // @MattJ Here userRooms is an array of each jabberID the user is on.
+    api.trigger('raiRoomsUpdated', userRooms);
 
-        api.listen.on('chatRoomActivityIndicators', jid => {
-            window.dispatchEvent(new CustomEvent('newMessage', {
-                detail: {
-                    jid,
-                },
-            }));
-        });
-    },
+    api.listen.on('chatRoomActivityIndicators', jid => {
+      window.dispatchEvent(new CustomEvent('newMessage', {
+        detail: {
+          jid,
+        },
+      }));
+    });
+  },
 });
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index f180e50..613139f 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -14,224 +14,224 @@ import './plugins/sib-remove-notifications.js';
 import './plugins/sib-subscribe-to-rai.js';
 
 export const SolidXMPPChat = {
-    name: 'solid-xmpp-chat',
-    use: [StoreMixin],
-    attributes: {
-        authentication: {
-            type: String,
-            default: 'login',
-        },
-        autoLogin: {
-            type: Boolean,
-            default: true,
-        },
-        i18n: {
-            type: String,
-            default: 'fr',
-        },
-        websocketUrl: {
-            type: String,
-            default: 'wss://jabber.happy-dev.fr/xmpp-websocket',
-        },
-    },
-
-    get extra_context() {
-        return {
-            'foaf': 'http://xmlns.com/foaf/0.1/',
-            'chatProfile': 'http://happy-dev.fr/owl/#chatProfile',
-            'jabberID': 'foaf:jabberID',
-        };
-    },
-
-    async created() {
-        const check_identified = await document.querySelector('sib-auth').getUserIdToken();
-        if (check_identified) {
-            this.element.attachShadow({ mode: 'open' });
-            this.importCSS(`${ComponentPath}/dist/conversejs/converse.min.css?min`);
-            this.importCSS(`${ComponentPath}/dist/index.css?min`);
-            if (typeof converse_sib === 'undefined') {
-                this.initializeConverse();
-            }
-        } // Else, not logged in on page load (even if not on chat)
+  name: 'solid-xmpp-chat',
+  use: [StoreMixin],
+  attributes: {
+    authentication: {
+      type: String,
+      default: 'login',
     },
-
-    importCSS(path) {
-        let link = document.createElement('link');
-        link.rel = 'stylesheet';
-        link.href = path;
-        this.element.shadowRoot.append(link);
+    autoLogin: {
+      type: Boolean,
+      default: true,
     },
-
-    empty() {
-        this.element.innerHTML = 'Loading...';
+    i18n: {
+      type: String,
+      default: 'fr',
     },
-
-    async populate() {
-        if (typeof converse_sib !== 'undefined') {
-            await converse_sib.loaded_deferred;
-            if (this.resource) {
-                if (await this.resource.jabberRoom) {
-                    this.jid = await this.resource['jabberID'];
-                } else {
-                    this.jid = await this.resource['chatProfile.jabberID'];
-                    const user = await document.querySelector('sib-auth').getUser();
-                    const userProfile = await store.getData(user['@id'], this.context);
-                    const contactsURL = await userProfile['contacts.@id'];
-                    const contactInterval = setInterval(async () => {
-                        let retry = false;
-                        let userContacts = [];
-                        for (let contact of await userProfile['contacts.ldp:contains']) {
-                            if (contact) {
-                                userContacts.push(await contact['contact.@id']);
-                            } else {
-                                retry = true;
-                            }
-                        }
-                        if (!retry) {
-                            clearInterval(contactInterval);
-                            if (!userContacts.includes(this.resource['@id'])) {
-                                store.post({
-                                    'contact': this.resource['@id'],
-                                    '@context': this.context,
-                                }, contactsURL);
-                            }
-                        }
-                    }, 100);
-                }
-                await converse_sib.connected_deferred;
-
-                window.dispatchEvent(new CustomEvent('sib-change-chat', {
-                    detail: {
-                        jid: this.jid,
-                        is_groupchat: await this.resource.jabberRoom,
-                        root: this.element.shadowRoot,
-                    },
-                }));
-
-                window.dispatchEvent(new CustomEvent('read', {
-                    detail: {
-                        resource: {
-                            '@id': this.resource['@id'],
-                        },
-                    },
-                }));
-            }
-        } // Else, not logged in, on chat change
+    websocketUrl: {
+      type: String,
+      default: 'wss://jabber.happy-dev.fr/xmpp-websocket',
     },
-
-    removeConverseDatabase() {
-        for (let key in sessionStorage) {
-            if (sessionStorage.hasOwnProperty(key) && /converse/.test(key)) {
-                sessionStorage.removeItem(key);
+  },
+
+  get extra_context() {
+    return {
+      'foaf': 'http://xmlns.com/foaf/0.1/',
+      'chatProfile': 'http://happy-dev.fr/owl/#chatProfile',
+      'jabberID': 'foaf:jabberID',
+    };
+  },
+
+  async created() {
+    const check_identified = await document.querySelector('sib-auth').getUserIdToken();
+    if (check_identified) {
+      this.element.attachShadow({ mode: 'open' });
+      this.importCSS(`${ComponentPath}/dist/conversejs/converse.min.css?min`);
+      this.importCSS(`${ComponentPath}/dist/index.css?min`);
+      if (typeof converse_sib === 'undefined') {
+        this.initializeConverse();
+      }
+    } // Else, not logged in on page load (even if not on chat)
+  },
+
+  importCSS(path) {
+    let link = document.createElement('link');
+    link.rel = 'stylesheet';
+    link.href = path;
+    this.element.shadowRoot.append(link);
+  },
+
+  empty() {
+    this.element.innerHTML = 'Loading...';
+  },
+
+  async populate() {
+    if (typeof converse_sib !== 'undefined') {
+      await converse_sib.loaded_deferred;
+      if (this.resource) {
+        if (await this.resource.jabberRoom) {
+          this.jid = await this.resource['jabberID'];
+        } else {
+          this.jid = await this.resource['chatProfile.jabberID'];
+          const user = await document.querySelector('sib-auth').getUser();
+          const userProfile = await store.getData(user['@id'], this.context);
+          const contactsURL = await userProfile['contacts.@id'];
+          const contactInterval = setInterval(async () => {
+            let retry = false;
+            let userContacts = [];
+            for (let contact of await userProfile['contacts.ldp:contains']) {
+              if (contact) {
+                userContacts.push(await contact['contact.@id']);
+              } else {
+                retry = true;
+              }
             }
-        }
-        for (let key in localStorage) {
-            if (localStorage.hasOwnProperty(key) && /converse/.test(key)) {
-                localStorage.removeItem(key);
+            if (!retry) {
+              clearInterval(contactInterval);
+              if (!userContacts.includes(this.resource['@id'])) {
+                store.post({
+                  'contact': this.resource['@id'],
+                  '@context': this.context,
+                }, contactsURL);
+              }
             }
+          }, 100);
         }
-        indexedDB.deleteDatabase('converse-persistent');
-    },
-
-    initializeConverse() {
-        window.converse_sib = {};
-
-        // Deferred resolved at the end of this function
-        converse_sib.loaded_deferred = new Deferred();
-
-        // Deferred resolved after converse.initialize
-        converse_sib.connected_deferred = new Deferred();
-
-        this.removeConverseDatabase();
-
-        // Initialize deferred resolution plugin
-        setTimeout(async () => {
-
-            // Initialize deferred resolution plugin
-            converse.plugins.add('sib-connected', {
-                initialize() {
-                    const { api } = this._converse;
-                    api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
-                },
-            });
-
-            const user = await document.querySelector('sib-auth').getUser();
-            const userProfile = await store.getData(user['@id'], this.context);
-            const jabberID = await userProfile['chatProfile.jabberID'];
+        await converse_sib.connected_deferred;
+
+        window.dispatchEvent(new CustomEvent('sib-change-chat', {
+          detail: {
+            jid: this.jid,
+            is_groupchat: await this.resource.jabberRoom,
+            root: this.element.shadowRoot,
+          },
+        }));
+
+        window.dispatchEvent(new CustomEvent('read', {
+          detail: {
+            resource: {
+              '@id': this.resource['@id'],
+            },
+          },
+        }));
+      }
+    } // Else, not logged in, on chat change
+  },
+
+  removeConverseDatabase() {
+    for (let key in sessionStorage) {
+      if (sessionStorage.hasOwnProperty(key) && /converse/.test(key)) {
+        sessionStorage.removeItem(key);
+      }
+    }
+    for (let key in localStorage) {
+      if (localStorage.hasOwnProperty(key) && /converse/.test(key)) {
+        localStorage.removeItem(key);
+      }
+    }
+    indexedDB.deleteDatabase('converse-persistent');
+  },
+
+  initializeConverse() {
+    window.converse_sib = {};
+
+    // Deferred resolved at the end of this function
+    converse_sib.loaded_deferred = new Deferred();
+
+    // Deferred resolved after converse.initialize
+    converse_sib.connected_deferred = new Deferred();
+
+    this.removeConverseDatabase();
+
+    // Initialize deferred resolution plugin
+    setTimeout(async () => {
+
+      // Initialize deferred resolution plugin
+      converse.plugins.add('sib-connected', {
+        initialize() {
+          const { api } = this._converse;
+          api.listen.on('connectionInitialized', converse_sib.connected_deferred.resolve);
+        },
+      });
 
-            if (this.resource) {
-                if (await this.resource.jabberRoom) {
-                    this.jid = await this.resource['jabberID'];
-                } else {
-                    this.jid = await this.resource['chatProfile.jabberID'];
-                }
-            } else {
-                this.jid = jabberID;
-            }
+      const user = await document.querySelector('sib-auth').getUser();
+      const userProfile = await store.getData(user['@id'], this.context);
+      const jabberID = await userProfile['chatProfile.jabberID'];
 
-            const idToken = await document.querySelector('sib-auth').getUserIdToken();
-
-            converse.initialize({
-                'assets_path': (/skypack/.test(ComponentPath) ? ComponentPath.replace('cdn.skypack.dev', 'unpkg.com') : ComponentPath) + '/dist/conversejs/',
-                'authentication': this.element.dataset.authentication || 'login',
-                'password': idToken,
-                'allow_bookmarks': false,
-                'allow_chat_pending_contacts': true,
-                'allow_message_retraction': 'moderator',
-                'allow_non_roster_messaging': true,
-                'allow_dragresize': false,
-                'allow_logout': false,
-                'archived_messages_page_size': '30',
-                'auto_list_rooms': true,
-                'auto_login': this.element.dataset.autoLogin === 'true',
-                'auto_join_on_invite': true,
-                'auto_reconnect': true,
-                'auto_register_muc_nickname': false,
-                'websocket_url': this.element.dataset.websocketUrl || 'wss://jabber.happy-dev.fr/xmpp-websocket',
-                'enable_smacks': true,
-                'clear_messages_on_reconnection': false,
-                'discover_connection_methods': false,
-                'jid': jabberID.toLowerCase(),
-                'i18n': this.element.dataset.i18n || 'fr',
-                'loglevel': 'fatal',
-                'message_archiving': 'always',
-                'message_archiving_timeout': 60000,
-                'muc_disable_slash_commands': true,
-                'muc_hats': ['hats', 'vcard_roles', 'admin'],
-                'role_affiliation_hat_conversions': { 'admin': 'Administrateur' },
-                'muc_nickname_from_jid': false,
-                'muc_fetch_members': true,
-                'muc_show_info_messages': [],
-                'play_sounds': false,
-                'root': this.element.shadowRoot,
-                'show_client_info': false,
-                'show_desktop_notifications': false,
-                'persistent_store': 'none',
-                'sounds_path': ComponentPath + '/dist/conversejs/',
-                'show_send_button': false,
-                'view_mode': 'fullscreen',
-                'visible_toolbar_buttons': {
-                    call: false,
-                    spoiler: false,
-                    emoji: true,
-                    fileupload: true, // Not working in current Converse
-                    toggle_occupants: false,
-                },
-                'whitelisted_plugins': [
-                    'converse-rai',
-                    'sib-chat-navigation',
-                    'sib-connected',
-                    'sib-custom-hats',
-                    'sib-disconnected',
-                    'sib-mam-history',
-                    'sib-remove-notifications',
-                    'sib-subscribe-to-rai',
-                ],
-            });
-
-            converse_sib.loaded_deferred.resolve();
-        }, 0);
-    },
+      if (this.resource) {
+        if (await this.resource.jabberRoom) {
+          this.jid = await this.resource['jabberID'];
+        } else {
+          this.jid = await this.resource['chatProfile.jabberID'];
+        }
+      } else {
+        this.jid = jabberID;
+      }
+
+      const idToken = await document.querySelector('sib-auth').getUserIdToken();
+
+      converse.initialize({
+        'assets_path': (/skypack/.test(ComponentPath) ? ComponentPath.replace('cdn.skypack.dev', 'unpkg.com') : ComponentPath) + '/dist/conversejs/',
+        'authentication': this.element.dataset.authentication || 'login',
+        'password': idToken,
+        'allow_bookmarks': false,
+        'allow_chat_pending_contacts': true,
+        'allow_message_retraction': 'moderator',
+        'allow_non_roster_messaging': true,
+        'allow_dragresize': false,
+        'allow_logout': false,
+        'archived_messages_page_size': '30',
+        'auto_list_rooms': true,
+        'auto_login': this.element.dataset.autoLogin === 'true',
+        'auto_join_on_invite': true,
+        'auto_reconnect': true,
+        'auto_register_muc_nickname': false,
+        'websocket_url': this.element.dataset.websocketUrl || 'wss://jabber.happy-dev.fr/xmpp-websocket',
+        'enable_smacks': true,
+        'clear_messages_on_reconnection': false,
+        'discover_connection_methods': false,
+        'jid': jabberID.toLowerCase(),
+        'i18n': this.element.dataset.i18n || 'fr',
+        'loglevel': 'fatal',
+        'message_archiving': 'always',
+        'message_archiving_timeout': 60000,
+        'muc_disable_slash_commands': true,
+        'muc_hats': ['hats', 'vcard_roles', 'admin'],
+        'role_affiliation_hat_conversions': { 'admin': 'Administrateur' },
+        'muc_nickname_from_jid': false,
+        'muc_fetch_members': true,
+        'muc_show_info_messages': [],
+        'play_sounds': false,
+        'root': this.element.shadowRoot,
+        'show_client_info': false,
+        'show_desktop_notifications': false,
+        'persistent_store': 'none',
+        'sounds_path': ComponentPath + '/dist/conversejs/',
+        'show_send_button': false,
+        'view_mode': 'fullscreen',
+        'visible_toolbar_buttons': {
+          call: false,
+          spoiler: false,
+          emoji: true,
+          fileupload: true, // Not working in current Converse
+          toggle_occupants: false,
+        },
+        'whitelisted_plugins': [
+          'converse-rai',
+          'sib-chat-navigation',
+          'sib-connected',
+          'sib-custom-hats',
+          'sib-disconnected',
+          'sib-mam-history',
+          'sib-remove-notifications',
+          'sib-subscribe-to-rai',
+        ],
+      });
+
+      converse_sib.loaded_deferred.resolve();
+    }, 0);
+  },
 };
 
 Sib.register(SolidXMPPChat);
diff --git a/src/utils.js b/src/utils.js
index 0275089..01f067a 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,10 +1,10 @@
 export class Deferred {
-    constructor() {
-        this.promise = new Promise(function(resolve, reject) {
-            this.resolve = resolve;
-            this.reject = reject;
-        }.bind(this));
-        this.then = this.promise.then.bind(this.promise);
-        this.catch = this.promise.catch.bind(this.promise);
-    }
+  constructor() {
+    this.promise = new Promise(function(resolve, reject) {
+      this.resolve = resolve;
+      this.reject = reject;
+    }.bind(this));
+    this.then = this.promise.then.bind(this.promise);
+    this.catch = this.promise.catch.bind(this.promise);
+  }
 }
-- 
GitLab