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

Commit cbb34d8

Browse files
Make CallHandler more EventEmittery (#6704)
* sharedInstance() -> instance Signed-off-by: Šimon Brandner <[email protected]> * Use CallState event instead of dispatching Signed-off-by: Šimon Brandner <[email protected]> * Simplifie some code Signed-off-by: Šimon Brandner <[email protected]> * Use a method to start a call instead of the dispatcher Signed-off-by: Šimon Brandner <[email protected]> * Use a method instead of place_conference_call Signed-off-by: Šimon Brandner <[email protected]> * Make terminateCallApp() and hangupCallApp() public Signed-off-by: Šimon Brandner <[email protected]> * Use hangupAllCalls() instead of the dispatcher Signed-off-by: Šimon Brandner <[email protected]> * Make dialNumber(), startTransferToMatrixID() and startTransferToPhoneNumber() public instead of using the dispatcher Signed-off-by: Šimon Brandner <[email protected]> * Use answerCall() instead of using the dispatcher Signed-off-by: Šimon Brandner <[email protected]> * Use hangupOrReject() instead of the dispatcher Signed-off-by: Šimon Brandner <[email protected]> * Update docs Signed-off-by: Šimon Brandner <[email protected]> * Improve TS Signed-off-by: Šimon Brandner <[email protected]> * Dispatch call_state, see element-hq/element-web#18823 (comment) Signed-off-by: Šimon Brandner <[email protected]> * Add missing import Signed-off-by: Šimon Brandner <[email protected]>
1 parent e3187ed commit cbb34d8

23 files changed

+287
-498
lines changed

src/CallHandler.tsx

Lines changed: 167 additions & 248 deletions
Large diffs are not rendered by default.

src/Lifecycle.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ async function startMatrixClient(startSyncing = true): Promise<void> {
794794
DMRoomMap.makeShared().start();
795795
IntegrationManagers.sharedInstance().startWatching();
796796
ActiveWidgetStore.instance.start();
797-
CallHandler.sharedInstance().start();
797+
CallHandler.instance.start();
798798

799799
// Start Mjolnir even though we haven't checked the feature flag yet. Starting
800800
// the thing just wastes CPU cycles, but should result in no actual functionality
@@ -897,7 +897,7 @@ async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void
897897
*/
898898
export function stopMatrixClient(unsetClient = true): void {
899899
Notifier.stop();
900-
CallHandler.sharedInstance().stop();
900+
CallHandler.instance.stop();
901901
UserActivity.sharedInstance().stop();
902902
TypingStore.sharedInstance().reset();
903903
Presence.stop();

src/SlashCommands.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ export const Commands = [
10371037

10381038
return success((async () => {
10391039
if (isPhoneNumber) {
1040-
const results = await CallHandler.sharedInstance().pstnLookup(this.state.value);
1040+
const results = await CallHandler.instance.pstnLookup(this.state.value);
10411041
if (!results || results.length === 0 || !results[0].userid) {
10421042
throw new Error("Unable to find Matrix ID for phone number");
10431043
}
@@ -1089,7 +1089,7 @@ export const Commands = [
10891089
description: _td("Places the call in the current room on hold"),
10901090
category: CommandCategories.other,
10911091
runFn: function(roomId, args) {
1092-
const call = CallHandler.sharedInstance().getCallForRoom(roomId);
1092+
const call = CallHandler.instance.getCallForRoom(roomId);
10931093
if (!call) {
10941094
return reject("No active call in this room");
10951095
}
@@ -1103,7 +1103,7 @@ export const Commands = [
11031103
description: _td("Takes the call in the current room off hold"),
11041104
category: CommandCategories.other,
11051105
runFn: function(roomId, args) {
1106-
const call = CallHandler.sharedInstance().getCallForRoom(roomId);
1106+
const call = CallHandler.instance.getCallForRoom(roomId);
11071107
if (!call) {
11081108
return reject("No active call in this room");
11091109
}

src/VoipUserMapper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default class VoipUserMapper {
3636
}
3737

3838
private async userToVirtualUser(userId: string): Promise<string> {
39-
const results = await CallHandler.sharedInstance().sipVirtualLookup(userId);
39+
const results = await CallHandler.instance.sipVirtualLookup(userId);
4040
if (results.length === 0 || !results[0].fields.lookup_success) return null;
4141
return results[0].userid;
4242
}
@@ -97,11 +97,11 @@ export default class VoipUserMapper {
9797
}
9898

9999
public async onNewInvitedRoom(invitedRoom: Room): Promise<void> {
100-
if (!CallHandler.sharedInstance().getSupportsVirtualRooms()) return;
100+
if (!CallHandler.instance.getSupportsVirtualRooms()) return;
101101

102102
const inviterId = invitedRoom.getDMInviter();
103103
logger.log(`Checking virtual-ness of room ID ${invitedRoom.roomId}, invited by ${inviterId}`);
104-
const result = await CallHandler.sharedInstance().sipNativeLookup(inviterId);
104+
const result = await CallHandler.instance.sipNativeLookup(inviterId);
105105
if (result.length === 0) {
106106
return;
107107
}

src/components/structures/CallEventGrouper.ts

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { CallEvent, CallState, CallType, MatrixCall } from "matrix-js-sdk/src/we
2020
import CallHandler, { CallHandlerEvent } from '../../CallHandler';
2121
import { EventEmitter } from 'events';
2222
import { MatrixClientPeg } from "../../MatrixClientPeg";
23-
import defaultDispatcher from "../../dispatcher/dispatcher";
2423

2524
export enum CallEventGrouperEvent {
2625
StateChanged = "state_changed",
@@ -52,8 +51,8 @@ export default class CallEventGrouper extends EventEmitter {
5251
constructor() {
5352
super();
5453

55-
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallsChanged, this.setCall);
56-
CallHandler.sharedInstance().addListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
54+
CallHandler.instance.addListener(CallHandlerEvent.CallsChanged, this.setCall);
55+
CallHandler.instance.addListener(CallHandlerEvent.SilencedCallsChanged, this.onSilencedCallsChanged);
5756
}
5857

5958
private get invite(): MatrixEvent {
@@ -114,41 +113,31 @@ export default class CallEventGrouper extends EventEmitter {
114113
}
115114

116115
private onSilencedCallsChanged = () => {
117-
const newState = CallHandler.sharedInstance().isCallSilenced(this.callId);
116+
const newState = CallHandler.instance.isCallSilenced(this.callId);
118117
this.emit(CallEventGrouperEvent.SilencedChanged, newState);
119118
};
120119

121120
private onLengthChanged = (length: number): void => {
122121
this.emit(CallEventGrouperEvent.LengthChanged, length);
123122
};
124123

125-
public answerCall = () => {
126-
defaultDispatcher.dispatch({
127-
action: 'answer',
128-
room_id: this.roomId,
129-
});
124+
public answerCall = (): void => {
125+
CallHandler.instance.answerCall(this.roomId);
130126
};
131127

132-
public rejectCall = () => {
133-
defaultDispatcher.dispatch({
134-
action: 'reject',
135-
room_id: this.roomId,
136-
});
128+
public rejectCall = (): void => {
129+
CallHandler.instance.hangupOrReject(this.roomId, true);
137130
};
138131

139-
public callBack = () => {
140-
defaultDispatcher.dispatch({
141-
action: 'place_call',
142-
type: this.isVoice ? CallType.Voice : CallType.Video,
143-
room_id: this.roomId,
144-
});
132+
public callBack = (): void => {
133+
CallHandler.instance.placeCall(this.roomId, this.isVoice ? CallType.Voice : CallType.Video);
145134
};
146135

147136
public toggleSilenced = () => {
148-
const silenced = CallHandler.sharedInstance().isCallSilenced(this.callId);
137+
const silenced = CallHandler.instance.isCallSilenced(this.callId);
149138
silenced ?
150-
CallHandler.sharedInstance().unSilenceCall(this.callId) :
151-
CallHandler.sharedInstance().silenceCall(this.callId);
139+
CallHandler.instance.unSilenceCall(this.callId) :
140+
CallHandler.instance.silenceCall(this.callId);
152141
};
153142

154143
private setCallListeners() {
@@ -174,7 +163,7 @@ export default class CallEventGrouper extends EventEmitter {
174163
private setCall = () => {
175164
if (this.call) return;
176165

177-
this.call = CallHandler.sharedInstance().getCallById(this.callId);
166+
this.call = CallHandler.instance.getCallById(this.callId);
178167
this.setCallListeners();
179168
this.setState();
180169
};

src/components/structures/LeftPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
340340

341341
// If we have dialer support, show a button to bring up the dial pad
342342
// to start a new call
343-
if (CallHandler.sharedInstance().getSupportsPstnProtocol()) {
343+
if (CallHandler.instance.getSupportsPstnProtocol()) {
344344
dialPadButton =
345345
<AccessibleTooltipButton
346346
className={classNames("mx_LeftPanel_dialPadButton", {})}

src/components/structures/LoggedInView.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import { getKeyBindingsManager, NavigationAction, RoomAction } from '../../KeyBi
5353
import { IOpts } from "../../createRoom";
5454
import SpacePanel from "../views/spaces/SpacePanel";
5555
import { replaceableComponent } from "../../utils/replaceableComponent";
56-
import CallHandler from '../../CallHandler';
56+
import CallHandler, { CallHandlerEvent } from '../../CallHandler';
5757
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
5858
import AudioFeedArrayForCall from '../views/voip/AudioFeedArrayForCall';
5959
import { OwnProfileStore } from '../../stores/OwnProfileStore';
@@ -164,7 +164,7 @@ class LoggedInView extends React.Component<IProps, IState> {
164164
// use compact timeline view
165165
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
166166
usageLimitDismissed: false,
167-
activeCalls: CallHandler.sharedInstance().getAllActiveCalls(),
167+
activeCalls: CallHandler.instance.getAllActiveCalls(),
168168
};
169169

170170
// stash the MatrixClient in case we log out before we are unmounted
@@ -181,7 +181,7 @@ class LoggedInView extends React.Component<IProps, IState> {
181181

182182
componentDidMount() {
183183
document.addEventListener('keydown', this.onNativeKeyDown, false);
184-
this.dispatcherRef = dis.register(this.onAction);
184+
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.onCallState);
185185

186186
this.updateServerNoticeEvents();
187187

@@ -212,6 +212,7 @@ class LoggedInView extends React.Component<IProps, IState> {
212212

213213
componentWillUnmount() {
214214
document.removeEventListener('keydown', this.onNativeKeyDown, false);
215+
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.onCallState);
215216
dis.unregister(this.dispatcherRef);
216217
this._matrixClient.removeListener("accountData", this.onAccountData);
217218
this._matrixClient.removeListener("sync", this.onSync);
@@ -222,6 +223,12 @@ class LoggedInView extends React.Component<IProps, IState> {
222223
this.resizer.detach();
223224
}
224225

226+
private onCallState = (): void => {
227+
const activeCalls = CallHandler.instance.getAllActiveCalls();
228+
if (activeCalls === this.state.activeCalls) return;
229+
this.setState({ activeCalls });
230+
};
231+
225232
private refreshBackgroundImage = async (): Promise<void> => {
226233
let backgroundImage = SettingsStore.getValue("RoomList.backgroundImage");
227234
if (backgroundImage) {
@@ -233,18 +240,6 @@ class LoggedInView extends React.Component<IProps, IState> {
233240
this.setState({ backgroundImage });
234241
};
235242

236-
private onAction = (payload): void => {
237-
switch (payload.action) {
238-
case 'call_state': {
239-
const activeCalls = CallHandler.sharedInstance().getAllActiveCalls();
240-
if (activeCalls !== this.state.activeCalls) {
241-
this.setState({ activeCalls });
242-
}
243-
break;
244-
}
245-
}
246-
};
247-
248243
public canResetTimelineInRoom = (roomId: string) => {
249244
if (!this._roomView.current) {
250245
return true;

src/components/structures/MatrixChat.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ import { makeRoomPermalink } from "../../utils/permalinks/Permalinks";
108108
import { copyPlaintext } from "../../utils/strings";
109109
import { PosthogAnalytics } from '../../PosthogAnalytics';
110110
import { initSentry } from "../../sentry";
111+
import CallHandler from "../../CallHandler";
111112

112113
import { logger } from "matrix-js-sdk/src/logger";
113114
import { showSpaceInvite } from "../../utils/space";
@@ -604,7 +605,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
604605
}
605606
break;
606607
case 'logout':
607-
dis.dispatch({ action: "hangup_all" });
608+
CallHandler.instance.hangupAllCalls();
608609
Lifecycle.logout();
609610
break;
610611
case 'require_registration':

src/components/structures/RoomView.tsx

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
3434
import ResizeNotifier from '../../utils/ResizeNotifier';
3535
import ContentMessages from '../../ContentMessages';
3636
import Modal from '../../Modal';
37-
import CallHandler, { PlaceCallType } from '../../CallHandler';
37+
import CallHandler, { CallHandlerEvent } from '../../CallHandler';
3838
import dis from '../../dispatcher/dispatcher';
3939
import * as Rooms from '../../Rooms';
4040
import eventSearch, { searchPagination } from '../../Searching';
@@ -66,7 +66,7 @@ import { IOOBData, IThreepidInvite } from "../../stores/ThreepidInviteStore";
6666
import EffectsOverlay from "../views/elements/EffectsOverlay";
6767
import { containsEmoji } from '../../effects/utils';
6868
import { CHAT_EFFECTS } from '../../effects';
69-
import { CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
69+
import { CallState, CallType, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
7070
import WidgetStore from "../../stores/WidgetStore";
7171
import { UPDATE_EVENT } from "../../stores/AsyncStore";
7272
import Notifier from "../../Notifier";
@@ -669,6 +669,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
669669
}
670670

671671
componentDidUpdate() {
672+
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.onCallState);
672673
if (this.roomView.current) {
673674
const roomView = this.roomView.current;
674675
if (!roomView.ondrop) {
@@ -699,6 +700,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
699700
// (We could use isMounted, but facebook have deprecated that.)
700701
this.unmounted = true;
701702

703+
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.onCallState);
704+
702705
// update the scroll map before we get unmounted
703706
if (this.state.roomId) {
704707
RoomScrollStateStore.setScrollState(this.state.roomId, this.getScrollState());
@@ -822,6 +825,15 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
822825
}
823826
};
824827

828+
private onCallState = (roomId: string): void => {
829+
// don't filter out payloads for room IDs other than props.room because
830+
// we may be interested in the conf 1:1 room
831+
832+
if (!roomId) return;
833+
const call = this.getCallForRoom();
834+
this.setState({ callState: call ? call.state : null });
835+
};
836+
825837
private onAction = payload => {
826838
switch (payload.action) {
827839
case 'message_sent':
@@ -843,21 +855,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
843855
case Action.UploadCanceled:
844856
this.forceUpdate();
845857
break;
846-
case 'call_state': {
847-
// don't filter out payloads for room IDs other than props.room because
848-
// we may be interested in the conf 1:1 room
849-
850-
if (!payload.room_id) {
851-
return;
852-
}
853-
854-
const call = this.getCallForRoom();
855-
856-
this.setState({
857-
callState: call ? call.state : null,
858-
});
859-
break;
860-
}
861858
case 'appsDrawer':
862859
this.setState({
863860
showApps: payload.show,
@@ -1531,12 +1528,8 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
15311528
return ret;
15321529
}
15331530

1534-
private onCallPlaced = (type: PlaceCallType) => {
1535-
dis.dispatch({
1536-
action: 'place_call',
1537-
type: type,
1538-
room_id: this.state.room.roomId,
1539-
});
1531+
private onCallPlaced = (type: CallType): void => {
1532+
CallHandler.instance.placeCall(this.state.room?.roomId, type);
15401533
};
15411534

15421535
private onAppsClick = () => {
@@ -1748,7 +1741,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
17481741
if (!this.state.room) {
17491742
return null;
17501743
}
1751-
return CallHandler.sharedInstance().getCallForRoom(this.state.room.roomId);
1744+
return CallHandler.instance.getCallForRoom(this.state.room.roomId);
17521745
}
17531746

17541747
// this has to be a proper method rather than an unnamed function,

src/components/views/context_menus/CallContextMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default class CallContextMenu extends React.Component<IProps> {
4545
};
4646

4747
onUnholdClick = () => {
48-
CallHandler.sharedInstance().setActiveCallRoomId(this.props.call.roomId);
48+
CallHandler.instance.setActiveCallRoomId(this.props.call.roomId);
4949

5050
this.props.onFinished();
5151
};

0 commit comments

Comments
 (0)