@@ -2914,6 +2914,33 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
29142914 return this . getType ( ) === RoomType . ElementVideo ;
29152915 }
29162916
2917+ private roomNameGenerator ( state : RoomNameState ) : string {
2918+ if ( this . client . roomNameGenerator ) {
2919+ const name = this . client . roomNameGenerator ( this . roomId , state ) ;
2920+ if ( name !== null ) {
2921+ return name ;
2922+ }
2923+ }
2924+
2925+ switch ( state . type ) {
2926+ case RoomNameType . Actual :
2927+ return state . name ;
2928+ case RoomNameType . Generated :
2929+ switch ( state . subtype ) {
2930+ case "Inviting" :
2931+ return `Inviting ${ memberNamesToRoomName ( state . names , state . count ) } ` ;
2932+ default :
2933+ return memberNamesToRoomName ( state . names , state . count ) ;
2934+ }
2935+ case RoomNameType . EmptyRoom :
2936+ if ( state . oldName ) {
2937+ return `Empty room (was ${ state . oldName } )` ;
2938+ } else {
2939+ return "Empty room" ;
2940+ }
2941+ }
2942+ }
2943+
29172944 /**
29182945 * This is an internal method. Calculates the name of the room from the current
29192946 * room state.
@@ -2928,14 +2955,20 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
29282955 // check for an alias, if any. for now, assume first alias is the
29292956 // official one.
29302957 const mRoomName = this . currentState . getStateEvents ( EventType . RoomName , "" ) ;
2931- if ( mRoomName && mRoomName . getContent ( ) && mRoomName . getContent ( ) . name ) {
2932- return mRoomName . getContent ( ) . name ;
2958+ if ( mRoomName ?. getContent ( ) . name ) {
2959+ return this . roomNameGenerator ( {
2960+ type : RoomNameType . Actual ,
2961+ name : mRoomName . getContent ( ) . name ,
2962+ } ) ;
29332963 }
29342964 }
29352965
29362966 const alias = this . getCanonicalAlias ( ) ;
29372967 if ( alias ) {
2938- return alias ;
2968+ return this . roomNameGenerator ( {
2969+ type : RoomNameType . Actual ,
2970+ name : alias ,
2971+ } ) ;
29392972 }
29402973
29412974 const joinedMemberCount = this . currentState . getJoinedMemberCount ( ) ;
@@ -2967,8 +3000,7 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
29673000 } ) ;
29683001 } else {
29693002 let otherMembers = this . currentState . getMembers ( ) . filter ( ( m ) => {
2970- return m . userId !== userId &&
2971- ( m . membership === "invite" || m . membership === "join" ) ;
3003+ return m . userId !== userId && ( m . membership === "invite" || m . membership === "join" ) ;
29723004 } ) ;
29733005 otherMembers = otherMembers . filter ( ( { userId } ) => {
29743006 // filter service members
@@ -2986,24 +3018,33 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
29863018 }
29873019
29883020 if ( inviteJoinCount ) {
2989- return memberNamesToRoomName ( otherNames , inviteJoinCount ) ;
3021+ return this . roomNameGenerator ( {
3022+ type : RoomNameType . Generated ,
3023+ names : otherNames ,
3024+ count : inviteJoinCount ,
3025+ } ) ;
29903026 }
29913027
29923028 const myMembership = this . getMyMembership ( ) ;
29933029 // if I have created a room and invited people through
29943030 // 3rd party invites
29953031 if ( myMembership == 'join' ) {
2996- const thirdPartyInvites =
2997- this . currentState . getStateEvents ( EventType . RoomThirdPartyInvite ) ;
3032+ const thirdPartyInvites = this . currentState . getStateEvents ( EventType . RoomThirdPartyInvite ) ;
29983033
2999- if ( thirdPartyInvites && thirdPartyInvites . length ) {
3034+ if ( thirdPartyInvites ? .length ) {
30003035 const thirdPartyNames = thirdPartyInvites . map ( ( i ) => {
30013036 return i . getContent ( ) . display_name ;
30023037 } ) ;
30033038
3004- return `Inviting ${ memberNamesToRoomName ( thirdPartyNames ) } ` ;
3039+ return this . roomNameGenerator ( {
3040+ type : RoomNameType . Generated ,
3041+ subtype : "Inviting" ,
3042+ names : thirdPartyNames ,
3043+ count : thirdPartyNames . length + 1 ,
3044+ } ) ;
30053045 }
30063046 }
3047+
30073048 // let's try to figure out who was here before
30083049 let leftNames = otherNames ;
30093050 // if we didn't have heroes, try finding them in the room state
@@ -3014,11 +3055,20 @@ export class Room extends TypedEventEmitter<EmittedEvents, RoomEventHandlerMap>
30143055 m . membership !== "join" ;
30153056 } ) . map ( ( m ) => m . name ) ;
30163057 }
3058+
3059+ let oldName : string ;
30173060 if ( leftNames . length ) {
3018- return `Empty room (was ${ memberNamesToRoomName ( leftNames ) } )` ;
3019- } else {
3020- return "Empty room" ;
3061+ oldName = this . roomNameGenerator ( {
3062+ type : RoomNameType . Generated ,
3063+ names : leftNames ,
3064+ count : leftNames . length + 1 ,
3065+ } ) ;
30213066 }
3067+
3068+ return this . roomNameGenerator ( {
3069+ type : RoomNameType . EmptyRoom ,
3070+ oldName,
3071+ } ) ;
30223072 }
30233073
30243074 /**
@@ -3203,8 +3253,33 @@ const ALLOWED_TRANSITIONS: Record<EventStatus, EventStatus[]> = {
32033253 [ EventStatus . CANCELLED ] : [ ] ,
32043254} ;
32053255
3206- // TODO i18n
3207- function memberNamesToRoomName ( names : string [ ] , count = ( names . length + 1 ) ) {
3256+ export enum RoomNameType {
3257+ EmptyRoom ,
3258+ Generated ,
3259+ Actual ,
3260+ }
3261+
3262+ export interface EmptyRoomNameState {
3263+ type : RoomNameType . EmptyRoom ;
3264+ oldName ?: string ;
3265+ }
3266+
3267+ export interface GeneratedRoomNameState {
3268+ type : RoomNameType . Generated ;
3269+ subtype ?: "Inviting" ;
3270+ names : string [ ] ;
3271+ count : number ;
3272+ }
3273+
3274+ export interface ActualRoomNameState {
3275+ type : RoomNameType . Actual ;
3276+ name : string ;
3277+ }
3278+
3279+ export type RoomNameState = EmptyRoomNameState | GeneratedRoomNameState | ActualRoomNameState ;
3280+
3281+ // Can be overriden by IMatrixClientCreateOpts::memberNamesToRoomNameFn
3282+ function memberNamesToRoomName ( names : string [ ] , count : number ) : string {
32083283 const countWithoutMe = count - 1 ;
32093284 if ( ! names . length ) {
32103285 return "Empty room" ;
0 commit comments