diff --git a/src/models/room-state.ts b/src/models/room-state.ts index 52d520be177..89b36cb4c5f 100644 --- a/src/models/room-state.ts +++ b/src/models/room-state.ts @@ -25,6 +25,7 @@ import { TypedEventEmitter } from "./typed-event-emitter"; import { Beacon, BeaconEvent, BeaconEventHandlerMap, getBeaconInfoIdentifier, BeaconIdentifier } from "./beacon"; import { TypedReEmitter } from "../ReEmitter"; import { M_BEACON, M_BEACON_INFO } from "../@types/beacon"; +import { UNSTABLE_ELEMENT_FUNCTIONAL_USERS } from "../@types/event" export interface IMarkerFoundOptions { /** Whether the timeline was empty before the marker event arrived in the @@ -220,6 +221,17 @@ export class RoomState extends TypedEventEmitter this.summaryJoinedMemberCount = count; } + /** + * Returns the number of joined non-functional members in this room + * This method caches the result. + * @returns The number of non-functional members in this room whose membership is 'join' + */ + public getJoinedFunctionalMemberCount(): number { + return this.getFunctionalMembers().reduce((count, m) => { + return this.getMembers().find((member) => member.userId === m)?.membership === "join" ? count + 1 : count; + }, 0); + } + /** * Returns the number of invited members in this room * @returns The number of members in this room whose membership is 'invite' @@ -236,6 +248,16 @@ export class RoomState extends TypedEventEmitter return this.invitedMemberCount; } + /** + * Returns the number of invited members in this room + * @returns The number of members in this room whose membership is 'invite' + */ + public getInvitedFunctionalMemberCount(): number { + return this.getFunctionalMembers().reduce((count, m) => { + return this.getMembers().find((member) => member.userId === m)?.membership === "invite" ? count + 1 : count; + }, 0); + } + /** * Set the amount of invited members in this room * @param count - the amount of invited members @@ -252,6 +274,20 @@ export class RoomState extends TypedEventEmitter return Object.values(this.members); } + /** + * Get all functional members in this room. + * @returns A list of MXID Strings. + */ + public getFunctionalMembers(): String[] { + const [functionalUsersStateEvent] = this.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name); + + if (Array.isArray(functionalUsersStateEvent?.getContent().service_members)) { + return functionalUsersStateEvent.getContent().service_members; + } + + return []; + } + /** * Get all RoomMembers in this room, excluding the user IDs provided. * @param excludedIds - The user IDs to exclude. diff --git a/src/models/room.ts b/src/models/room.ts index 67aea690756..911a18083da 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -915,7 +915,7 @@ export class Room extends ReadReceipt { } public getAvatarFallbackMember(): RoomMember | undefined { - const memberCount = this.getInvitedAndJoinedMemberCount(); + const memberCount = this.getInvitedAndJoinedMemberCount() - this.getInvitedAndJoinedFunctionalMemberCount(); if (memberCount > 2) { return; } @@ -1699,6 +1699,25 @@ export class Room extends ReadReceipt { return this.currentState.getInvitedMemberCount(); } + /** + * Returns the number of joined non-functional members in this room + * This method caches the result. + * This is a wrapper around the method of the same name in roomState, returning + * its result for the room's current state. + * @returns The number of non-functional members in this room whose membership is 'join' + */ + public getJoinedFunctionalMemberCount(): number { + return this.currentState.getJoinedFunctionalMemberCount(); + } + + /** + * Returns the number of non-functional invited members in this room + * @returns The number of non-functional members in this room whose membership is 'invite' + */ + public getInvitedFunctionalMemberCount(): number { + return this.currentState.getInvitedFunctionalMemberCount(); + } + /** * Returns the number of invited + joined members in this room * @returns The number of members in this room whose membership is 'invite' or 'join' @@ -1707,6 +1726,14 @@ export class Room extends ReadReceipt { return this.getInvitedMemberCount() + this.getJoinedMemberCount(); } + /** + * Returns the number of invited + joined non-functional members in this room + * @returns The number of non-functional members in this room whose membership is 'invite' or 'join' + */ + public getInvitedAndJoinedFunctionalMemberCount(): number { + return this.getInvitedFunctionalMemberCount() + this.getJoinedFunctionalMemberCount(); + } + /** * Get a list of members with given membership state. * @param membership - The membership state.