From c24aa5895e5490d5e48e8fe1a4ea4923cc749af0 Mon Sep 17 00:00:00 2001
From: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Date: Sun, 8 Oct 2023 10:58:53 +0530
Subject: [PATCH] consider membership change with reason change

---
 src/app/hooks/useMemberEventParser.tsx      | 3 ++-
 src/app/hooks/useRoomLatestRenderedEvent.ts | 3 ++-
 src/app/organisms/room/RoomTimeline.tsx     | 4 ++--
 src/app/utils/room.ts                       | 4 ++++
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/app/hooks/useMemberEventParser.tsx b/src/app/hooks/useMemberEventParser.tsx
index ecb6f66b..367e76d9 100644
--- a/src/app/hooks/useMemberEventParser.tsx
+++ b/src/app/hooks/useMemberEventParser.tsx
@@ -3,6 +3,7 @@ import { IconSrc, Icons } from 'folds';
 import { MatrixEvent } from 'matrix-js-sdk';
 import { IMemberContent, Membership } from '../../types/matrix/room';
 import { getMxIdLocalPart } from '../utils/matrix';
+import { isMembershipChanged } from '../utils/room';
 
 export type ParsedResult = {
   icon: IconSrc;
@@ -27,7 +28,7 @@ export const useMemberEventParser = (): MemberEventParser => {
     const senderName = getMxIdLocalPart(senderId);
     const userName = content.displayname || getMxIdLocalPart(userId);
 
-    if (content.membership !== prevContent.membership) {
+    if (isMembershipChanged(mEvent)) {
       if (content.membership === Membership.Invite) {
         if (prevContent.membership === Membership.Knock) {
           return {
diff --git a/src/app/hooks/useRoomLatestRenderedEvent.ts b/src/app/hooks/useRoomLatestRenderedEvent.ts
index 295d1030..428e7b52 100644
--- a/src/app/hooks/useRoomLatestRenderedEvent.ts
+++ b/src/app/hooks/useRoomLatestRenderedEvent.ts
@@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
 import { settingsAtom } from '../state/settings';
 import { useSetting } from '../state/hooks/settings';
 import { MessageEvent, StateEvent } from '../../types/matrix/room';
+import { isMembershipChanged } from '../utils/room';
 
 export const useRoomLatestRenderedEvent = (room: Room) => {
   const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents');
@@ -20,7 +21,7 @@ export const useRoomLatestRenderedEvent = (room: Room) => {
         if (!evt) continue;
         if (evt.isRelation()) continue;
         if (evt.getType() === StateEvent.RoomMember) {
-          const membershipChanged = evt.getContent().membership !== evt.getPrevContent().membership;
+          const membershipChanged = isMembershipChanged(evt);
           if (membershipChanged && hideMembershipEvents) continue;
           if (!membershipChanged && hideNickAvatarEvents) continue;
           return evt;
diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx
index c41bfbb8..6f72c975 100644
--- a/src/app/organisms/room/RoomTimeline.tsx
+++ b/src/app/organisms/room/RoomTimeline.tsx
@@ -83,6 +83,7 @@ import {
   decryptAllTimelineEvent,
   getMemberDisplayName,
   getReactionContent,
+  isMembershipChanged,
 } from '../../utils/room';
 import { useSetting } from '../../state/hooks/settings';
 import { settingsAtom } from '../../state/settings';
@@ -1306,8 +1307,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
       );
     },
     renderRoomMember: (mEventId, mEvent, item) => {
-      const membershipChanged =
-        mEvent.getContent().membership !== mEvent.getPrevContent().membership;
+      const membershipChanged = isMembershipChanged(mEvent);
       if (membershipChanged && hideMembershipEvents) return null;
       if (!membershipChanged && hideNickAvatarEvents) return null;
 
diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts
index f8637833..af9505d4 100644
--- a/src/app/utils/room.ts
+++ b/src/app/utils/room.ts
@@ -278,6 +278,10 @@ export const getMemberAvatarMxc = (room: Room, userId: string): string | undefin
   return member?.getMxcAvatarUrl();
 };
 
+export const isMembershipChanged = (mEvent: MatrixEvent): boolean =>
+  mEvent.getContent().membership !== mEvent.getPrevContent().membership ||
+  mEvent.getContent().reason !== mEvent.getPrevContent().reason;
+
 export const decryptAllTimelineEvent = async (mx: MatrixClient, timeline: EventTimeline) => {
   const crypto = mx.getCrypto();
   if (!crypto) return;