@@ -16,7 +16,11 @@ limitations under the License.
1616import { AbortError } from "p-retry" ;
1717
1818import { EventType } from "../@types/event.ts" ;
19- import { UpdateDelayedEventAction } from "../@types/requests.ts" ;
19+ import {
20+ type ISendEventResponse ,
21+ type SendDelayedEventResponse ,
22+ UpdateDelayedEventAction ,
23+ } from "../@types/requests.ts" ;
2024import { type MatrixClient } from "../client.ts" ;
2125import { UnsupportedDelayedEventsEndpointError } from "../errors.ts" ;
2226import { ConnectionError , HTTPError , MatrixError } from "../http-api/errors.ts" ;
@@ -314,6 +318,8 @@ export class MembershipManager
314318 MatrixClient ,
315319 | "getUserId"
316320 | "getDeviceId"
321+ | "sendStateEvent"
322+ | "_unstable_sendDelayedStateEvent"
317323 | "_unstable_updateDelayedEvent"
318324 | "_unstable_sendStickyEvent"
319325 | "_unstable_sendStickyDelayedEvent"
@@ -413,6 +419,11 @@ export class MembershipManager
413419 private get delayedLeaveEventRestartLocalTimeoutMs ( ) : number {
414420 return this . joinConfig ?. delayedLeaveEventRestartLocalTimeoutMs ?? 2000 ;
415421 }
422+
423+ private get useStickyEvents ( ) : boolean {
424+ return this . joinConfig ?. useStickyEvents ?? false ;
425+ }
426+
416427 // LOOP HANDLER:
417428 private async membershipLoopHandler ( type : MembershipActionType ) : Promise < ActionUpdate > {
418429 switch ( type ) {
@@ -467,23 +478,36 @@ export class MembershipManager
467478 }
468479 }
469480
481+ // an abstraction to switch between sending state or a sticky event
482+ private clientSendDelayedEvent : ( myMembership : EmptyObject ) => Promise < SendDelayedEventResponse > = (
483+ myMembership ,
484+ ) =>
485+ this . useStickyEvents
486+ ? this . client . _unstable_sendStickyDelayedEvent (
487+ this . room . roomId ,
488+ STICK_DURATION_MS ,
489+ { delay : this . delayedLeaveEventDelayMs } ,
490+ null ,
491+ EventType . GroupCallMemberPrefix ,
492+ Object . assign ( myMembership , { sticky_key : this . stateKey } ) ,
493+ )
494+ : this . client . _unstable_sendDelayedStateEvent (
495+ this . room . roomId ,
496+ { delay : this . delayedLeaveEventDelayMs } ,
497+ EventType . GroupCallMemberPrefix ,
498+ myMembership ,
499+ this . stateKey ,
500+ ) ;
501+ private sendDelayedEventMethodName : ( ) => string = ( ) =>
502+ this . useStickyEvents ? "_unstable_sendStickyDelayedEvent" : "_unstable_sendDelayedStateEvent" ;
503+
470504 // HANDLERS (used in the membershipLoopHandler)
471505 private async sendOrResendDelayedLeaveEvent ( ) : Promise < ActionUpdate > {
472506 // We can reach this at the start of a call (where we do not yet have a membership: state.hasMemberStateEvent=false)
473507 // or during a call if the state event canceled our delayed event or caused by an unexpected error that removed our delayed event.
474508 // (Another client could have canceled it, the homeserver might have removed/lost it due to a restart, ...)
475509 // In the `then` and `catch` block we treat both cases differently. "if (this.state.hasMemberStateEvent) {} else {}"
476- return await this . client
477- . _unstable_sendStickyDelayedEvent (
478- this . room . roomId ,
479- STICK_DURATION_MS ,
480- {
481- delay : this . delayedLeaveEventDelayMs ,
482- } ,
483- null ,
484- EventType . GroupCallMemberPrefix ,
485- { sticky_key : this . stateKey } as EmptyObject & { sticky_key : string } , // leave event
486- )
510+ return await this . clientSendDelayedEvent ( { } )
487511 . then ( ( response ) => {
488512 this . state . expectedServerDelayLeaveTs = Date . now ( ) + this . delayedLeaveEventDelayMs ;
489513 this . setAndEmitProbablyLeft ( false ) ;
@@ -507,7 +531,7 @@ export class MembershipManager
507531 if ( this . manageMaxDelayExceededSituation ( e ) ) {
508532 return createInsertActionUpdate ( repeatActionType ) ;
509533 }
510- const update = this . actionUpdateFromErrors ( e , repeatActionType , "_unstable_sendStickyDelayedEvent" ) ;
534+ const update = this . actionUpdateFromErrors ( e , repeatActionType , this . sendDelayedEventMethodName ( ) ) ;
511535 if ( update ) return update ;
512536
513537 if ( this . state . hasMemberStateEvent ) {
@@ -663,12 +687,27 @@ export class MembershipManager
663687 } ) ;
664688 }
665689
690+ private clientSendMembership : ( myMembership : SessionMembershipData | EmptyObject ) => Promise < ISendEventResponse > = (
691+ myMembership ,
692+ ) =>
693+ this . useStickyEvents
694+ ? this . client . _unstable_sendStickyEvent (
695+ this . room . roomId ,
696+ STICK_DURATION_MS ,
697+ null ,
698+ EventType . GroupCallMemberPrefix ,
699+ Object . assign ( myMembership , { sticky_key : this . stateKey } ) ,
700+ )
701+ : this . client . sendStateEvent (
702+ this . room . roomId ,
703+ EventType . GroupCallMemberPrefix ,
704+ myMembership ,
705+ this . stateKey ,
706+ ) ;
707+ private sendMembershipMethodName : ( ) => string = ( ) =>
708+ this . useStickyEvents ? "_unstable_sendStickyEvent" : "sendStateEvent" ;
666709 private async sendJoinEvent ( ) : Promise < ActionUpdate > {
667- return await this . client
668- . _unstable_sendStickyEvent ( this . room . roomId , STICK_DURATION_MS , null , EventType . GroupCallMemberPrefix , {
669- ...this . makeMyMembership ( this . membershipEventExpiryMs ) ,
670- sticky_key : this . stateKey ,
671- } )
710+ return await this . clientSendMembership ( this . makeMyMembership ( this . membershipEventExpiryMs ) )
672711 . then ( ( ) => {
673712 this . setAndEmitProbablyLeft ( false ) ;
674713 this . state . startTime = Date . now ( ) ;
@@ -703,7 +742,7 @@ export class MembershipManager
703742 const update = this . actionUpdateFromErrors (
704743 e ,
705744 MembershipActionType . SendJoinEvent ,
706- "_unstable_sendStickyEvent" ,
745+ this . sendMembershipMethodName ( ) ,
707746 ) ;
708747 if ( update ) return update ;
709748 throw e ;
@@ -712,11 +751,9 @@ export class MembershipManager
712751
713752 private async updateExpiryOnJoinedEvent ( ) : Promise < ActionUpdate > {
714753 const nextExpireUpdateIteration = this . state . expireUpdateIterations + 1 ;
715- return await this . client
716- . _unstable_sendStickyEvent ( this . room . roomId , STICK_DURATION_MS , null , EventType . GroupCallMemberPrefix , {
717- ...this . makeMyMembership ( this . membershipEventExpiryMs ) ,
718- sticky_key : this . stateKey ,
719- } )
754+ return await this . clientSendMembership (
755+ this . makeMyMembership ( this . membershipEventExpiryMs * nextExpireUpdateIteration ) ,
756+ )
720757 . then ( ( ) => {
721758 // Success, we reset retries and schedule update.
722759 this . resetRateLimitCounter ( MembershipActionType . UpdateExpiry ) ;
@@ -734,22 +771,15 @@ export class MembershipManager
734771 const update = this . actionUpdateFromErrors (
735772 e ,
736773 MembershipActionType . UpdateExpiry ,
737- "_unstable_sendStickyEvent" ,
774+ this . sendMembershipMethodName ( ) ,
738775 ) ;
739776 if ( update ) return update ;
740777
741778 throw e ;
742779 } ) ;
743780 }
744781 private async sendFallbackLeaveEvent ( ) : Promise < ActionUpdate > {
745- return await this . client
746- . _unstable_sendStickyEvent (
747- this . room . roomId ,
748- STICK_DURATION_MS ,
749- null ,
750- EventType . GroupCallMemberPrefix ,
751- { sticky_key : this . stateKey } as EmptyObject & { sticky_key : string } , // leave event
752- )
782+ return await this . clientSendMembership ( { } )
753783 . then ( ( ) => {
754784 this . resetRateLimitCounter ( MembershipActionType . SendLeaveEvent ) ;
755785 this . state . hasMemberStateEvent = false ;
@@ -759,7 +789,7 @@ export class MembershipManager
759789 const update = this . actionUpdateFromErrors (
760790 e ,
761791 MembershipActionType . SendLeaveEvent ,
762- "_unstable_sendStickyEvent" ,
792+ this . sendMembershipMethodName ( ) ,
763793 ) ;
764794 if ( update ) return update ;
765795 throw e ;
0 commit comments