From 873067d2a292b9a9808a2cda7c927c345396ee2b Mon Sep 17 00:00:00 2001 From: John Livingston Date: Tue, 16 Jan 2024 18:52:18 +0100 Subject: [PATCH] Fix #136: display anonymous users at the end of the participants list --- CHANGELOG.md | 4 +++- conversejs/build-conversejs.sh | 3 ++- conversejs/builtin.ts | 35 +++++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d598551..831430d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,9 @@ * UX: add a label ('Choose a nickname to enter') for the anonymous nickname prompt. Fix #287. * Translation updates: German, French. * New Swedish translations. -* UI/UX improvment: hide nickname changes when previous nickname was like "Anonymous 12345". Helps to improve performances when massive anonymous users are joining (#138), and prevent displaying unnecessary messages (#111). +* UI/UX improvments: + * hide nickname changes when previous nickname was like "Anonymous 12345". Helps to improve performances when massive anonymous users are joining (#138), and prevent displaying unnecessary messages (#111). + * display anonymous users at the end of the participants list (Fix #136) * Using patched ConverseJS for performance improvment (related to #96): * debounce MUC sidebar rendering in ConverseJS (Fix #138) * force history pruning, even if messages keep coming (Fix #140) diff --git a/conversejs/build-conversejs.sh b/conversejs/build-conversejs.sh index 447bfc2f..56849290 100644 --- a/conversejs/build-conversejs.sh +++ b/conversejs/build-conversejs.sh @@ -14,7 +14,8 @@ CONVERSE_COMMIT="" # This version includes following changes: # - #converse.js/3300: Adding the maxWait option for `debouncedPruneHistory` # - #converse.js/3302: debounce MUC sidebar rendering -CONVERSE_COMMIT="732f58b50d1b1cf0d3f091668057032fb52b164a" +# - Fix: refresh the MUC sidebar when participants collection is sorted +CONVERSE_COMMIT="4861395f047e4abee2b30271c80d29a86baf7828" CONVERSE_REPO="https://github.com/JohnXLivingston/converse.js" rootdir="$(pwd)" diff --git a/conversejs/builtin.ts b/conversejs/builtin.ts index 3b9cc1c8..9167ac51 100644 --- a/conversejs/builtin.ts +++ b/conversejs/builtin.ts @@ -111,7 +111,7 @@ window.initConverse = async function initConverse (initConverseParams: InitConve // livechatSpecifics plugins add some customization for the livechat plugin. converse.plugins.add('livechatSpecifics', { - dependencies: ['converse-muc'], + dependencies: ['converse-muc', 'converse-muc-views'], overrides: { ChatRoom: { getActionInfoMessage: function (this: any, code: string, nick: string, actor: any): any { @@ -120,14 +120,43 @@ window.initConverse = async function initConverse (initConverseParams: InitConve // they can all change their nicknames at the same time, generating a log of action messages. // To mitigate this, will don't display nickname changes if the previous nick is something like // 'Anonymous 12345'. - // To avoid displaying the message, we just have to return an empty one - // (createInfoMessage will ignore if !data.message). if (/^Anonymous \d+$/.test(nick)) { + // We are sorting anonymous users at the end, by overriding ChatRoomOccupants.comparator. + // But this has a caveat: occupants are not sorted again when nicknames changes... + // As a workaround, we re-sort the occupant list here, when we intercept a action info message + // from an anonymous user that has changed his nickname. + // FIXME: This is not very clean... but will do the work. + try { + // Moreover, we can't sort now, as the new nickname is not saved in the Collection... + // So using a setTimout + // FIXME: find a better way + setTimeout(() => this.occupants.sort(), 100) + } catch (err) { + console.error(err) + } + + // To avoid displaying the message, we just have to return an empty one + // (createInfoMessage will ignore if !data.message). return null } } return this.__super__.getActionInfoMessage(code, nick, actor) } + }, + ChatRoomOccupants: { + comparator: function (this: any, occupant1: any, occupant2: any): Number { + // Overriding Occupants comparators, to display anonymous users at the end of the list. + const nick1: string = occupant1.getDisplayName() + const nick2: string = occupant2.getDisplayName() + const b1 = nick1.startsWith('Anonymous ') + const b2 = nick2.startsWith('Anonymous ') + if (b1 === b2) { + // Both startswith anonymous, or non of it: fallback to the standard comparator. + return this.__super__.comparator(occupant1, occupant2) + } + // Else: Anonymous always last. + return b1 ? 1 : -1 + } } } })