@@ -31,6 +31,7 @@ import { EventSubscription } from 'fbemitter';
3131import PictureInPictureDragger from './PictureInPictureDragger' ;
3232
3333import { logger } from "matrix-js-sdk/src/logger" ;
34+ import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore' ;
3435
3536const SHOW_CALL_IN_STATES = [
3637 CallState . Connected ,
@@ -59,7 +60,9 @@ interface IState {
5960// (which should be a single element) of other calls.
6061// The primary will be the one not on hold, or an arbitrary one
6162// if they're all on hold)
62- function getPrimarySecondaryCalls ( calls : MatrixCall [ ] ) : [ MatrixCall , MatrixCall [ ] ] {
63+ function getPrimarySecondaryCallsForPip ( roomId : string ) : [ MatrixCall , MatrixCall [ ] ] {
64+ const calls = CallHandler . sharedInstance ( ) . getAllActiveCallsForPip ( roomId ) ;
65+
6366 let primary : MatrixCall = null ;
6467 let secondaries : MatrixCall [ ] = [ ] ;
6568
@@ -101,9 +104,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
101104
102105 const roomId = RoomViewStore . getRoomId ( ) ;
103106
104- const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCalls (
105- CallHandler . sharedInstance ( ) . getAllActiveCallsNotInRoom ( roomId ) ,
106- ) ;
107+ const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCallsForPip ( roomId ) ;
107108
108109 this . state = {
109110 roomId,
@@ -117,6 +118,10 @@ export default class CallPreview extends React.Component<IProps, IState> {
117118 this . roomStoreToken = RoomViewStore . addListener ( this . onRoomViewStoreUpdate ) ;
118119 this . dispatcherRef = dis . register ( this . onAction ) ;
119120 MatrixClientPeg . get ( ) . on ( CallEvent . RemoteHoldUnhold , this . onCallRemoteHold ) ;
121+ const room = MatrixClientPeg . get ( ) ?. getRoom ( this . state . roomId ) ;
122+ if ( room ) {
123+ WidgetLayoutStore . instance . on ( WidgetLayoutStore . emissionForRoom ( room ) , this . updateCalls ) ;
124+ }
120125 }
121126
122127 public componentWillUnmount ( ) {
@@ -127,18 +132,29 @@ export default class CallPreview extends React.Component<IProps, IState> {
127132 }
128133 dis . unregister ( this . dispatcherRef ) ;
129134 SettingsStore . unwatchSetting ( this . settingsWatcherRef ) ;
135+ const room = MatrixClientPeg . get ( ) . getRoom ( this . state . roomId ) ;
136+ WidgetLayoutStore . instance . off ( WidgetLayoutStore . emissionForRoom ( room ) , this . updateCalls ) ;
130137 }
131138
132139 private onRoomViewStoreUpdate = ( ) => {
133- if ( RoomViewStore . getRoomId ( ) === this . state . roomId ) return ;
134-
135- const roomId = RoomViewStore . getRoomId ( ) ;
136- const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCalls (
137- CallHandler . sharedInstance ( ) . getAllActiveCallsNotInRoom ( roomId ) ,
138- ) ;
140+ const newRoomId = RoomViewStore . getRoomId ( ) ;
141+ const oldRoomId = this . state . roomId ;
142+ if ( newRoomId === oldRoomId ) return ;
143+ // The WidgetLayoutStore observer always tracks the currently viewed Room,
144+ // so we don't end up with multiple observers and know what observer to remove on unmount
145+ const oldRoom = MatrixClientPeg . get ( ) ?. getRoom ( oldRoomId ) ;
146+ if ( oldRoom ) {
147+ WidgetLayoutStore . instance . off ( WidgetLayoutStore . emissionForRoom ( oldRoom ) , this . updateCalls ) ;
148+ }
149+ const newRoom = MatrixClientPeg . get ( ) ?. getRoom ( newRoomId ) ;
150+ if ( newRoom ) {
151+ WidgetLayoutStore . instance . on ( WidgetLayoutStore . emissionForRoom ( newRoom ) , this . updateCalls ) ;
152+ }
153+ if ( ! newRoomId ) return ;
139154
155+ const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCallsForPip ( newRoomId ) ;
140156 this . setState ( {
141- roomId,
157+ roomId : newRoomId ,
142158 primaryCall : primaryCall ,
143159 secondaryCall : secondaryCalls [ 0 ] ,
144160 } ) ;
@@ -157,9 +173,8 @@ export default class CallPreview extends React.Component<IProps, IState> {
157173 } ;
158174
159175 private updateCalls = ( ) => {
160- const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCalls (
161- CallHandler . sharedInstance ( ) . getAllActiveCallsNotInRoom ( this . state . roomId ) ,
162- ) ;
176+ if ( ! this . state . roomId ) return ;
177+ const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCallsForPip ( this . state . roomId ) ;
163178
164179 this . setState ( {
165180 primaryCall : primaryCall ,
@@ -168,9 +183,8 @@ export default class CallPreview extends React.Component<IProps, IState> {
168183 } ;
169184
170185 private onCallRemoteHold = ( ) => {
171- const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCalls (
172- CallHandler . sharedInstance ( ) . getAllActiveCallsNotInRoom ( this . state . roomId ) ,
173- ) ;
186+ if ( ! this . state . roomId ) return ;
187+ const [ primaryCall , secondaryCalls ] = getPrimarySecondaryCallsForPip ( this . state . roomId ) ;
174188
175189 this . setState ( {
176190 primaryCall : primaryCall ,
0 commit comments