Fix calls sometimes not knowing that they're presented (#31313)
Because RoomViewStore used two slightly different conditions, the Call.presented flag could get out of sync with the viewingCall flag. But these should effectively be the same thing. This was causing some subtle bugs if you would join a call, switch to another room, and then click back into the call room via the room list. The call would be visible but not know that it's presented, causing: 1. The hangup sound to get cut off at the end of the call 2. The widget to disappear immediately without offering a 'reconnect' button if you lose connectivity
This commit is contained in:
@@ -361,7 +361,17 @@ export class RoomViewStore extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
if (room && (payload.view_call || isVideoRoom(room))) {
|
||||
let viewingCall = payload.view_call;
|
||||
if (viewingCall === undefined) {
|
||||
// Default behavior: keep the same call state as before if viewing the same room
|
||||
if (payload.room_id === this.state.roomId) viewingCall = this.state.viewingCall;
|
||||
// Always view the call in video rooms
|
||||
else if (room && isVideoRoom(room)) viewingCall = true;
|
||||
// Otherwise, only view if actively connected
|
||||
else viewingCall = CallStore.instance.getActiveCall(payload.room_id) !== null;
|
||||
}
|
||||
|
||||
if (room && viewingCall) {
|
||||
let call = CallStore.instance.getCall(payload.room_id);
|
||||
// Start a call if not already there
|
||||
if (call === null) {
|
||||
@@ -421,11 +431,7 @@ export class RoomViewStore extends EventEmitter {
|
||||
replyingToEvent: null,
|
||||
viaServers: payload.via_servers ?? [],
|
||||
wasContextSwitch: payload.context_switch ?? false,
|
||||
viewingCall:
|
||||
payload.view_call ??
|
||||
(payload.room_id === this.state.roomId
|
||||
? this.state.viewingCall
|
||||
: CallStore.instance.getActiveCall(payload.room_id) !== null),
|
||||
viewingCall,
|
||||
};
|
||||
|
||||
// Allow being given an event to be replied to when switching rooms but sanity check its for this room
|
||||
|
||||
@@ -133,6 +133,7 @@ describe("PipContainer", () => {
|
||||
{
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
view_call: false, // We're testing PiP functionality, so view the timeline
|
||||
metricsTrigger: undefined,
|
||||
},
|
||||
true,
|
||||
|
||||
@@ -146,16 +146,6 @@ describe("RoomViewStore", function () {
|
||||
const room2 = new Room(roomId2, mockClient, userId);
|
||||
getRooms.mockReturnValue([room, room2]);
|
||||
|
||||
const viewCall = async (): Promise<void> => {
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
view_call: true,
|
||||
metricsTrigger: undefined,
|
||||
});
|
||||
await untilDispatch(Action.ViewRoom, dis);
|
||||
};
|
||||
|
||||
const dispatchPromptAskToJoin = async () => {
|
||||
dis.dispatch({ action: Action.PromptAskToJoin });
|
||||
await untilDispatch(Action.PromptAskToJoin, dis);
|
||||
@@ -404,11 +394,36 @@ describe("RoomViewStore", function () {
|
||||
const call = { presented: false } as Call;
|
||||
const getCallSpy = jest.spyOn(CallStore.instance, "getCall").mockReturnValue(call);
|
||||
await setupAsyncStoreWithClient(CallStore.instance, MatrixClientPeg.safeGet());
|
||||
await viewCall();
|
||||
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
view_call: true,
|
||||
metricsTrigger: undefined,
|
||||
});
|
||||
await untilDispatch(Action.ViewRoom, dis);
|
||||
|
||||
expect(getCallSpy).toHaveBeenCalledWith(roomId);
|
||||
expect(call.presented).toEqual(true);
|
||||
});
|
||||
|
||||
it("implicitly views an active call", async () => {
|
||||
const call = { presented: false } as Call;
|
||||
jest.spyOn(CallStore.instance, "getCall").mockReturnValue(call);
|
||||
jest.spyOn(CallStore.instance, "getActiveCall").mockImplementation((rId) => (rId === roomId ? call : null));
|
||||
await setupAsyncStoreWithClient(CallStore.instance, MatrixClientPeg.safeGet());
|
||||
|
||||
// View the room without explicitly setting view_call to true
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: roomId,
|
||||
metricsTrigger: undefined,
|
||||
});
|
||||
await untilDispatch(Action.ViewRoom, dis);
|
||||
|
||||
expect(call.presented).toEqual(true);
|
||||
});
|
||||
|
||||
it("should display an error message when the room is unreachable via the roomId", async () => {
|
||||
// When
|
||||
// View and wait for the room
|
||||
|
||||
Reference in New Issue
Block a user