浏览代码

Update `nick` attr on ChatRoom when user nick changes

JC Brand 2 年之前
父节点
当前提交
f014db8b7a
共有 4 个文件被更改,包括 58 次插入6 次删除
  1. 2 0
      CHANGES.md
  2. 4 0
      src/headless/plugins/muc/muc.js
  3. 2 0
      src/headless/plugins/muc/parsers.js
  4. 50 6
      src/plugins/muc-views/tests/nickname.js

+ 2 - 0
CHANGES.md

@@ -8,6 +8,8 @@
 - Remove the `converse-carbons` plugin and make carbons part of the `converse-chat` plugin.
 - Remove the `message_carbons` configuration setting. Carbons are now always enabled.
 - Move the `converse-oauth` plugin to the [community-plugins](https://github.com/conversejs/community-plugins)
+- Don't apply message corrections when the MUC occupant-id doesn't match.
+- Update `nick` attribute on ChatRoom when user nickname changes
 - #2936: Fix documentation about enable_smacks option, which is true by default.
 
 ## 9.1.1 (2022-05-05)

+ 4 - 0
src/headless/plugins/muc/muc.js

@@ -1727,6 +1727,10 @@ const ChatRoomMixin = {
             'resource': Strophe.getResourceFromJid(jid) || occupant?.attributes?.resource
         }
 
+        if (data.is_me && data.states.includes(converse.MUC_NICK_CHANGED_CODE)) {
+            this.save('nick', data.nick);
+        }
+
         if (occupant) {
             occupant.save(attributes);
         } else {

+ 2 - 0
src/headless/plugins/muc/parsers.js

@@ -343,6 +343,7 @@ export function parseMUCPresence (stanza, chatbox) {
     const from = stanza.getAttribute('from');
     const type = stanza.getAttribute('type');
     const data = {
+        'is_me': !!stanza.querySelector("status[code='110']"),
         'from': from,
         'occupant_id': getOccupantID(stanza, chatbox),
         'nick': Strophe.getResourceFromJid(from),
@@ -351,6 +352,7 @@ export function parseMUCPresence (stanza, chatbox) {
         'hats': [],
         'show': type !== 'unavailable' ? 'online' : 'offline'
     };
+
     Array.from(stanza.children).forEach(child => {
         if (child.matches('status')) {
             data.status = child.textContent || null;

+ 50 - 6
src/plugins/muc-views/tests/nickname.js

@@ -1,15 +1,20 @@
 /*global mock, converse */
 
-const { $pres, $iq, Strophe, sizzle, u }  = converse.env;
+const { $pres, $iq, Strophe, sizzle, u } = converse.env;
 
 describe("A MUC", function () {
 
     it("allows you to change your nickname via a modal",
             mock.initConverse([], {'view_mode': 'fullscreen'}, async function (_converse) {
 
+        const { stanza } = converse.env;
         const muc_jid = 'lounge@montague.lit';
         const nick = 'romeo';
-        await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
+        const model = await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
+
+        expect(model.get('nick')).toBe(nick);
+        expect(model.occupants.length).toBe(1);
+        expect(model.occupants.at(0).get('nick')).toBe(nick);
 
         const view = _converse.chatboxviews.get(muc_jid);
         const dropdown_item = view.querySelector(".open-nickname-modal");
@@ -31,6 +36,45 @@ describe("A MUC", function () {
         const sent_stanza = sent_stanzas.pop()
         expect(Strophe.serialize(sent_stanza).toLocaleString()).toBe(
             `<presence from="${_converse.jid}" id="${sent_stanza.getAttribute('id')}" to="${muc_jid}/${newnick}" xmlns="jabber:client"/>`);
+
+        // Two presence stanzas are received from the MUC service
+        _converse.connection._dataRecv(mock.createRequest(
+            stanza`
+            <presence
+                from='${muc_jid}/${nick}'
+                id='DC352437-C019-40EC-B590-AF29E879AF98'
+                to='${_converse.jid}'
+                type='unavailable'>
+            <x xmlns='http://jabber.org/protocol/muc#user'>
+                <item affiliation='member'
+                    jid='${_converse.jid}'
+                    nick='${newnick}'
+                    role='participant'/>
+                <status code='303'/>
+                <status code='110'/>
+            </x>
+            </presence>`
+        ));
+
+        expect(model.get('nick')).toBe(newnick);
+
+        _converse.connection._dataRecv(mock.createRequest(
+            stanza`
+            <presence
+                from='${muc_jid}/${newnick}'
+                id='5B4F27A4-25ED-43F7-A699-382C6B4AFC67'
+                to='${_converse.jid}'>
+            <x xmlns='http://jabber.org/protocol/muc#user'>
+                <item affiliation='member'
+                    jid='${_converse.jid}'
+                    role='participant'/>
+                <status code='110'/>
+            </x>
+            </presence>`
+        ));
+
+        await u.waitUntil(() => model.occupants.at(0).get('nick') === newnick);
+        expect(model.occupants.length).toBe(1);
     }));
 
     it("informs users if their nicknames have been changed.",
@@ -71,7 +115,7 @@ describe("A MUC", function () {
          *  </x>
          *  </presence>
          */
-        const __ = _converse.__;
+        const { __ } = _converse;
         await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'oldnick');
 
         const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -130,8 +174,9 @@ describe("A MUC", function () {
             __(_converse.muc.new_nickname_messages["303"], "newnick")
         );
         occupants = view.querySelector('.occupant-list');
-        expect(occupants.childElementCount).toBe(1);
-        expect(sizzle('.occupant-nick:first', occupants).pop().textContent.trim()).toBe("newnick");
+        await u.waitUntil(() => sizzle('.occupant-nick:first', occupants).pop().textContent.trim() === "newnick");
+        expect(view.model.occupants.length).toBe(1);
+        expect(view.model.get('nick')).toBe("newnick");
     }));
 
     describe("when being entered", function () {
@@ -423,4 +468,3 @@ describe("A MUC", function () {
         }));
     });
 });
-