ソースを参照

Handle message notifications about affiliation change for users not in a room

See https://git.happy-dev.fr/startinblox/components/sib-chat/issues/96
Dele Olajide 5 年 前
コミット
890db3427f
3 ファイル変更85 行追加0 行削除
  1. 3 0
      CHANGES.md
  2. 43 0
      spec/muc.js
  3. 39 0
      src/headless/converse-muc.js

+ 3 - 0
CHANGES.md

@@ -4,8 +4,11 @@
 
 - [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) is not set to `true` by default.
 - Refactor some presence and status handling code from `converse-core` into `@converse/headless/converse-status`.
+
+- Add support for [notifications about affiliation change for users not in a room](https://xmpp.org/extensions/xep-0045.html#example-196)
 - Add support for [XEP-0424 Message Retraction](http://localhost:3080/extensions/xep-0424.html)
 - Add support for [XEP-0425 Message Moderation](http://localhost:3080/extensions/xep-0425.html)
+
 - New API [\_converse.api.headlines](https://conversejs.org/docs/html/api/-_converse.api.headlines.html#.get)
 - New config option [allow_message_retraction](https://conversejs.org/docs/html/configuration.html#allow-message-retraction)
 - New config option [muc-show-logs-before-join](https://conversejs.org/docs/html/configuration.html#muc-show-logs-before-join)

+ 43 - 0
spec/muc.js

@@ -2906,6 +2906,49 @@
                 expect(info_msgs.pop().textContent.trim()).toBe("annoyingGuy is no longer a member of this groupchat");
                 done();
             }));
+
+            it("notifies user of role and affiliation changes for members not in the groupchat",
+                mock.initConverse(
+                    ['rosterGroupsFetched'], {},
+                    async function (done, _converse) {
+
+                const muc_jid = 'lounge@montague.lit';
+                await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
+                const view = _converse.api.chatviews.get(muc_jid);
+
+                let message = $msg({
+                    from: 'lounge@montague.lit',
+                    id: '2CF9013B-E8A8-42A1-9633-85AD7CA12F40',
+                    to: 'romeo@montague.lit'
+                })
+                .c('x', { 'xmlns': 'http://jabber.org/protocol/muc#user'})
+                .c('item', {
+                    'jid': 'annoyingguy@montague.lit',
+                    'affiliation': 'member',
+                    'role': 'none'
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(message));
+                await u.waitUntil(() => view.model.occupants.length > 1);
+                expect(view.model.occupants.length).toBe(2);
+                expect(view.model.occupants.findWhere({'jid': 'annoyingguy@montague.lit'}).get('affiliation')).toBe('member');
+
+                message = $msg({
+                    from: 'lounge@montague.lit',
+                    id: '2CF9013B-E8A8-42A1-9633-85AD7CA12F41',
+                    to: 'romeo@montague.lit'
+                })
+                .c('x', { 'xmlns': 'http://jabber.org/protocol/muc#user'})
+                .c('item', {
+                    'jid': 'annoyingguy@montague.lit',
+                    'affiliation': 'none',
+                    'role': 'none'
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(message));
+                expect(view.model.occupants.length).toBe(2);
+                expect(view.model.occupants.findWhere({'jid': 'annoyingguy@montague.lit'}).get('affiliation')).toBe('none');
+
+                done();
+            }));
         });
 
 

+ 39 - 0
src/headless/converse-muc.js

@@ -504,6 +504,38 @@ converse.plugins.add('converse-muc', {
                     }, null, 'message', 'groupchat', null, room_jid,
                     {'matchBareFromJid': true}
                 );
+                this.muc_notifications_handler = _converse.connection.addHandler(stanza => {
+                    const item = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, stanza).pop();
+
+                    if (item) {
+                        const from = stanza.getAttribute("from");
+                        const type = stanza.getAttribute("type");
+                        const affiliation = item.getAttribute('affiliation');
+                        const jid = item.getAttribute('jid');
+
+                        const data = {
+                          'from': from,
+                          'nick': Strophe.getNodeFromJid(jid),
+                          'type': type,
+                          'states': [],
+                          'show': type == 'unavailable' ? 'offline' : 'online',
+                          'affiliation': affiliation,
+                          'role': item.getAttribute('role'),
+                          'jid': Strophe.getBareJidFromJid(jid),
+                          'resource': Strophe.getResourceFromJid(jid)
+                        }
+
+                        const occupant = this.occupants.findOccupant({'jid': data.jid});
+
+                        if (occupant) {
+                          occupant.save(data);
+                        } else {
+                          this.occupants.create(data);
+                        }
+                    }
+                    return true;
+
+                }, Strophe.NS.MUC_USER, 'message', null, null, room_jid);
             },
 
             removeHandlers () {
@@ -521,6 +553,13 @@ converse.plugins.add('converse-muc', {
                     }
                     delete this.presence_handler;
                 }
+
+                if (this.muc_notifications_handler) {
+                    if (_converse.connection) {
+                        _converse.connection.deleteHandler(this.muc_notifications_handler);
+                    }
+                  delete this.muc_notifications_handler;
+                }
                 return this;
             },