Fix: member count in header and member list (#30982)
* fix: same member count in header and member list * test: update test * chore: use `useRoomMemberCount` to compute member count in member list * test: add event emitter function on mocked `room.currentState`
This commit is contained in:
@@ -38,6 +38,7 @@ import { isValid3pidInvite } from "../../../RoomInvite";
|
|||||||
import { type ThreePIDInvite } from "../../../models/rooms/ThreePIDInvite";
|
import { type ThreePIDInvite } from "../../../models/rooms/ThreePIDInvite";
|
||||||
import { type XOR } from "../../../@types/common";
|
import { type XOR } from "../../../@types/common";
|
||||||
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
||||||
|
import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
|
||||||
|
|
||||||
type Member = XOR<{ member: RoomMember }, { threePidInvite: ThreePIDInvite }>;
|
type Member = XOR<{ member: RoomMember }, { threePidInvite: ThreePIDInvite }>;
|
||||||
|
|
||||||
@@ -126,6 +127,9 @@ export function useMemberListViewModel(roomId: string): MemberListViewState {
|
|||||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
// This is the last known total number of members in this room.
|
// This is the last known total number of members in this room.
|
||||||
const [totalMemberCount, setTotalMemberCount] = useState(0);
|
const [totalMemberCount, setTotalMemberCount] = useState(0);
|
||||||
|
|
||||||
|
const memberCountWithout3Pid = useRoomMemberCount(room, { includeInvited: true });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the current number of members in the list.
|
* This is the current number of members in the list.
|
||||||
* This number will be less than the total number of members
|
* This number will be less than the total number of members
|
||||||
@@ -168,7 +172,7 @@ export function useMemberListViewModel(roomId: string): MemberListViewState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setMemberMap(newMemberMap);
|
setMemberMap(newMemberMap);
|
||||||
setMemberCount(joinedSdk.length + invitedSdk.length + threePidInvited.length);
|
setMemberCount(memberCountWithout3Pid + threePidInvited.length);
|
||||||
if (!searchQuery) {
|
if (!searchQuery) {
|
||||||
/**
|
/**
|
||||||
* Since searching for members only gives you the relevant
|
* Since searching for members only gives you the relevant
|
||||||
@@ -180,7 +184,7 @@ export function useMemberListViewModel(roomId: string): MemberListViewState {
|
|||||||
500,
|
500,
|
||||||
{ leading: true, trailing: true },
|
{ leading: true, trailing: true },
|
||||||
),
|
),
|
||||||
[sdkContext.memberListStore, roomId, room],
|
[sdkContext.memberListStore, roomId, room, memberCountWithout3Pid],
|
||||||
);
|
);
|
||||||
|
|
||||||
const isPresenceEnabled = useMemo(
|
const isPresenceEnabled = useMemo(
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export default function RoomHeader({
|
|||||||
const joinRule = useRoomState(room, (state) => state.getJoinRule());
|
const joinRule = useRoomState(room, (state) => state.getJoinRule());
|
||||||
|
|
||||||
const members = useRoomMembers(room, 2500);
|
const members = useRoomMembers(room, 2500);
|
||||||
const memberCount = useRoomMemberCount(room, { throttleWait: 2500 });
|
const memberCount = useRoomMemberCount(room, { throttleWait: 2500, includeInvited: true });
|
||||||
|
|
||||||
const {
|
const {
|
||||||
voiceCallDisabledReason,
|
voiceCallDisabledReason,
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ type RoomMemberCountOpts = {
|
|||||||
* Wait time between room member count update
|
* Wait time between room member count update
|
||||||
*/
|
*/
|
||||||
throttleWait?: number;
|
throttleWait?: number;
|
||||||
|
/**
|
||||||
|
* Whether to include invited members in the count
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
includeInvited?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,19 +53,21 @@ type RoomMemberCountOpts = {
|
|||||||
*/
|
*/
|
||||||
export const useRoomMemberCount = (
|
export const useRoomMemberCount = (
|
||||||
room: Room,
|
room: Room,
|
||||||
{ throttleWait }: RoomMemberCountOpts = { throttleWait: 250 },
|
{ throttleWait, includeInvited }: RoomMemberCountOpts = { throttleWait: 250, includeInvited: false },
|
||||||
): number => {
|
): number => {
|
||||||
const [count, setCount] = useState<number>(room.getJoinedMemberCount());
|
const [count, setCount] = useState<number>(
|
||||||
|
includeInvited ? room.getInvitedAndJoinedMemberCount() : room.getJoinedMemberCount(),
|
||||||
|
);
|
||||||
const throttledUpdate = useMemo(
|
const throttledUpdate = useMemo(
|
||||||
() =>
|
() =>
|
||||||
throttle(
|
throttle(
|
||||||
() => {
|
() => {
|
||||||
setCount(room.getJoinedMemberCount());
|
setCount(includeInvited ? room.getInvitedAndJoinedMemberCount() : room.getJoinedMemberCount());
|
||||||
},
|
},
|
||||||
throttleWait,
|
throttleWait,
|
||||||
{ leading: true, trailing: true },
|
{ leading: true, trailing: true },
|
||||||
),
|
),
|
||||||
[room, throttleWait],
|
[room, throttleWait, includeInvited],
|
||||||
);
|
);
|
||||||
|
|
||||||
useTypedEventEmitter(room.currentState, RoomStateEvent.Members, throttledUpdate);
|
useTypedEventEmitter(room.currentState, RoomStateEvent.Members, throttledUpdate);
|
||||||
|
|||||||
@@ -108,6 +108,12 @@ export async function renderMemberList(
|
|||||||
members: {},
|
members: {},
|
||||||
getMember: jest.fn(),
|
getMember: jest.fn(),
|
||||||
getStateEvents: ((eventType, stateKey) => (stateKey === undefined ? [] : null)) as RoomState["getStateEvents"], // ignore 3pid invites
|
getStateEvents: ((eventType, stateKey) => (stateKey === undefined ? [] : null)) as RoomState["getStateEvents"], // ignore 3pid invites
|
||||||
|
getInvitedMemberCount: jest.fn().mockReturnValue(0),
|
||||||
|
getJoinedMemberCount: jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue(adminUsers.length + moderatorUsers.length + defaultUsers.length),
|
||||||
|
on: jest.fn(),
|
||||||
|
off: jest.fn(),
|
||||||
} as unknown as RoomState;
|
} as unknown as RoomState;
|
||||||
for (const member of [...adminUsers, ...moderatorUsers, ...defaultUsers]) {
|
for (const member of [...adminUsers, ...moderatorUsers, ...defaultUsers]) {
|
||||||
memberListRoom.currentState.members[member.userId] = member;
|
memberListRoom.currentState.members[member.userId] = member;
|
||||||
|
|||||||
Reference in New Issue
Block a user