Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 37828ab

Browse files
authored
Maximised widgets always force a call to be shown in PIP mode (#7163)
1 parent ae0dba4 commit 37828ab

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

src/CallHandler.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,16 @@ export default class CallHandler extends EventEmitter {
380380
return callsNotInThatRoom;
381381
}
382382

383+
public getAllActiveCallsForPip(roomId: string) {
384+
const room = MatrixClientPeg.get().getRoom(roomId);
385+
if (WidgetLayoutStore.instance.hasMaximisedWidget(room)) {
386+
// This checks if there is space for the call view in the aux panel
387+
// If there is no space any call should be displayed in PiP
388+
return this.getAllActiveCalls();
389+
}
390+
return this.getAllActiveCallsNotInRoom(roomId);
391+
}
392+
383393
getTransfereeForCallId(callId: string): MatrixCall {
384394
return this.transferees[callId];
385395
}

src/components/views/voip/CallPreview.tsx

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { EventSubscription } from 'fbemitter';
3131
import PictureInPictureDragger from './PictureInPictureDragger';
3232

3333
import { logger } from "matrix-js-sdk/src/logger";
34+
import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore';
3435

3536
const 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

Comments
 (0)