From 8a7035d7c5bee6ab76438232cbf656f81a923aa6 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 19 Nov 2021 12:40:33 +0100 Subject: [PATCH 1/5] Maximised widgets call PIP --- src/CallHandler.tsx | 10 ++++++ src/components/views/voip/CallPreview.tsx | 41 +++++++++++++---------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 69b00927a9c..800d61cd451 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -380,6 +380,16 @@ export default class CallHandler extends EventEmitter { return callsNotInThatRoom; } + getAllActiveCallsForPip(roomId) { + const room = MatrixClientPeg.get().getRoom(roomId); + if (WidgetLayoutStore.instance.hasMaximisedWidget(room)) { + // This checks if there is space for the call view in the aux panel + // If there is no space any call should be displayed in PiP + return this.getAllActiveCalls(); + } + return this.getAllActiveCallsNotInRoom(roomId); + } + getTransfereeForCallId(callId: string): MatrixCall { return this.transferees[callId]; } diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index e34266616ea..3ce61b72e13 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -31,6 +31,7 @@ import { EventSubscription } from 'fbemitter'; import PictureInPictureDragger from './PictureInPictureDragger'; import { logger } from "matrix-js-sdk/src/logger"; +import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore'; const SHOW_CALL_IN_STATES = [ CallState.Connected, @@ -59,7 +60,9 @@ interface IState { // (which should be a single element) of other calls. // The primary will be the one not on hold, or an arbitrary one // if they're all on hold) -function getPrimarySecondaryCalls(calls: MatrixCall[]): [MatrixCall, MatrixCall[]] { +function getPrimarySecondaryCallsForPip(roomId): [MatrixCall, MatrixCall[]] { + const calls = CallHandler.sharedInstance().getAllActiveCallsForPip(roomId); + let primary: MatrixCall = null; let secondaries: MatrixCall[] = []; @@ -101,9 +104,7 @@ export default class CallPreview extends React.Component { const roomId = RoomViewStore.getRoomId(); - const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls( - CallHandler.sharedInstance().getAllActiveCallsNotInRoom(roomId), - ); + const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(roomId); this.state = { roomId, @@ -117,6 +118,8 @@ export default class CallPreview extends React.Component { this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate); this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold); + const room = MatrixClientPeg.get().getRoom(this.state.roomId); + WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); } public componentWillUnmount() { @@ -127,18 +130,24 @@ export default class CallPreview extends React.Component { } dis.unregister(this.dispatcherRef); SettingsStore.unwatchSetting(this.settingsWatcherRef); + const room = MatrixClientPeg.get().getRoom(this.state.roomId); + WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); } private onRoomViewStoreUpdate = () => { - if (RoomViewStore.getRoomId() === this.state.roomId) return; - - const roomId = RoomViewStore.getRoomId(); - const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls( - CallHandler.sharedInstance().getAllActiveCallsNotInRoom(roomId), - ); - + const newRoomId = RoomViewStore.getRoomId(); + const oldRoomId = this.state.roomId; + if (newRoomId === oldRoomId) return; + // The WidgetLayoutStore observer always tracks the currently viewed Room, + // so we don't end up with multiple observers and know what observer to remove on unmount + const newRoom = MatrixClientPeg.get().getRoom(newRoomId); + const oldRoom = MatrixClientPeg.get().getRoom(oldRoomId); + WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls); + WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls); + + const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(newRoomId); this.setState({ - roomId, + roomId: newRoomId, primaryCall: primaryCall, secondaryCall: secondaryCalls[0], }); @@ -157,9 +166,7 @@ export default class CallPreview extends React.Component { }; private updateCalls = () => { - const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls( - CallHandler.sharedInstance().getAllActiveCallsNotInRoom(this.state.roomId), - ); + const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId); this.setState({ primaryCall: primaryCall, @@ -168,9 +175,7 @@ export default class CallPreview extends React.Component { }; private onCallRemoteHold = () => { - const [primaryCall, secondaryCalls] = getPrimarySecondaryCalls( - CallHandler.sharedInstance().getAllActiveCallsNotInRoom(this.state.roomId), - ); + const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId); this.setState({ primaryCall: primaryCall, From 54c62df9b2c5d7cab45b65c03fa64842c669f8d2 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 22 Nov 2021 14:17:59 +0100 Subject: [PATCH 2/5] fix on/off --- src/components/views/voip/CallPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index 3ce61b72e13..e0c9ed65534 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -119,7 +119,7 @@ export default class CallPreview extends React.Component { this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold); const room = MatrixClientPeg.get().getRoom(this.state.roomId); - WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); + WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); } public componentWillUnmount() { From 57e11d37230429083c8e1591b31596d07ddc7ba9 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 22 Nov 2021 14:36:00 +0100 Subject: [PATCH 3/5] fix loading if there is no room open --- src/components/views/voip/CallPreview.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index e0c9ed65534..a8f5f35f3b3 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -119,7 +119,9 @@ export default class CallPreview extends React.Component { this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold); const room = MatrixClientPeg.get().getRoom(this.state.roomId); - WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); + if (room) { + WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); + } } public componentWillUnmount() { @@ -142,7 +144,9 @@ export default class CallPreview extends React.Component { // so we don't end up with multiple observers and know what observer to remove on unmount const newRoom = MatrixClientPeg.get().getRoom(newRoomId); const oldRoom = MatrixClientPeg.get().getRoom(oldRoomId); - WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls); + if (oldRoom) { + WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls); + } WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls); const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(newRoomId); From d8bd38255bd7440d2db5cdccc22ab60ee53dabd4 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 22 Nov 2021 14:48:38 +0100 Subject: [PATCH 4/5] check on roomId instead of room --- src/components/views/voip/CallPreview.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index a8f5f35f3b3..b24cfd5c3f1 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -118,7 +118,7 @@ export default class CallPreview extends React.Component { this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate); this.dispatcherRef = dis.register(this.onAction); MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold); - const room = MatrixClientPeg.get().getRoom(this.state.roomId); + const room = MatrixClientPeg.get()?.getRoom(this.state.roomId); if (room) { WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.updateCalls); } @@ -142,12 +142,15 @@ export default class CallPreview extends React.Component { if (newRoomId === oldRoomId) return; // The WidgetLayoutStore observer always tracks the currently viewed Room, // so we don't end up with multiple observers and know what observer to remove on unmount - const newRoom = MatrixClientPeg.get().getRoom(newRoomId); - const oldRoom = MatrixClientPeg.get().getRoom(oldRoomId); + const oldRoom = MatrixClientPeg.get()?.getRoom(oldRoomId); if (oldRoom) { WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(oldRoom), this.updateCalls); } - WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls); + const newRoom = MatrixClientPeg.get()?.getRoom(newRoomId); + if (newRoom) { + WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(newRoom), this.updateCalls); + } + if (!newRoomId) return; const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(newRoomId); this.setState({ @@ -170,6 +173,7 @@ export default class CallPreview extends React.Component { }; private updateCalls = () => { + if (!this.state.roomId) return; const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId); this.setState({ @@ -179,6 +183,7 @@ export default class CallPreview extends React.Component { }; private onCallRemoteHold = () => { + if (!this.state.roomId) return; const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId); this.setState({ From 1efec11737746c2f45555431d540abd59d60b43f Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 23 Nov 2021 12:07:41 +0100 Subject: [PATCH 5/5] type fixes (review) --- src/CallHandler.tsx | 2 +- src/components/views/voip/CallPreview.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index 800d61cd451..3a28be02108 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -380,7 +380,7 @@ export default class CallHandler extends EventEmitter { return callsNotInThatRoom; } - getAllActiveCallsForPip(roomId) { + public getAllActiveCallsForPip(roomId: string) { const room = MatrixClientPeg.get().getRoom(roomId); if (WidgetLayoutStore.instance.hasMaximisedWidget(room)) { // This checks if there is space for the call view in the aux panel diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx index b24cfd5c3f1..1c667e42291 100644 --- a/src/components/views/voip/CallPreview.tsx +++ b/src/components/views/voip/CallPreview.tsx @@ -60,7 +60,7 @@ interface IState { // (which should be a single element) of other calls. // The primary will be the one not on hold, or an arbitrary one // if they're all on hold) -function getPrimarySecondaryCallsForPip(roomId): [MatrixCall, MatrixCall[]] { +function getPrimarySecondaryCallsForPip(roomId: string): [MatrixCall, MatrixCall[]] { const calls = CallHandler.sharedInstance().getAllActiveCallsForPip(roomId); let primary: MatrixCall = null;