Make CallHandler more EventEmittery (#6704)

* sharedInstance() -> instance

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use CallState event instead of dispatching

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Simplifie some code

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use a method to start a call instead of the dispatcher

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use a method instead of place_conference_call

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Make terminateCallApp() and hangupCallApp() public

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use hangupAllCalls() instead of the dispatcher

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Make dialNumber(), startTransferToMatrixID() and startTransferToPhoneNumber() public instead of using the dispatcher

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use answerCall() instead of using the dispatcher

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Use hangupOrReject() instead of the dispatcher

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Update docs

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Improve TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Dispatch call_state, see https://github.com/vector-im/element-web/pull/18823#issuecomment-917377277

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Add missing import

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-11-30 19:09:13 +01:00 committed by GitHub
parent e3187ed15c
commit cbb34d8ac7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 300 additions and 511 deletions

View file

@ -20,8 +20,6 @@ import React from 'react';
import CallView from "./CallView";
import RoomViewStore from '../../../stores/RoomViewStore';
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
import dis from '../../../dispatcher/dispatcher';
import { ActionPayload } from '../../../dispatcher/payloads';
import PersistentApp from "../elements/PersistentApp";
import SettingsStore from "../../../settings/SettingsStore";
import { CallEvent, CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
@ -29,6 +27,8 @@ import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { EventSubscription } from 'fbemitter';
import PictureInPictureDragger from './PictureInPictureDragger';
import dis from '../../../dispatcher/dispatcher';
import { Action } from "../../../dispatcher/actions";
import { logger } from "matrix-js-sdk/src/logger";
import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore';
@ -61,7 +61,7 @@ interface IState {
// The primary will be the one not on hold, or an arbitrary one
// if they're all on hold)
function getPrimarySecondaryCallsForPip(roomId: string): [MatrixCall, MatrixCall[]] {
const calls = CallHandler.sharedInstance().getAllActiveCallsForPip(roomId);
const calls = CallHandler.instance.getAllActiveCallsForPip(roomId);
let primary: MatrixCall = null;
let secondaries: MatrixCall[] = [];
@ -114,9 +114,9 @@ export default class CallPreview extends React.Component<IProps, IState> {
}
public componentDidMount() {
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
CallHandler.instance.addListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.updateCalls);
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);
if (room) {
@ -125,12 +125,12 @@ export default class CallPreview extends React.Component<IProps, IState> {
}
public componentWillUnmount() {
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
CallHandler.instance.removeListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.updateCalls);
MatrixClientPeg.get().removeListener(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
if (this.roomStoreToken) {
this.roomStoreToken.remove();
}
dis.unregister(this.dispatcherRef);
SettingsStore.unwatchSetting(this.settingsWatcherRef);
const room = MatrixClientPeg.get().getRoom(this.state.roomId);
WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(room), this.updateCalls);
@ -160,19 +160,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
});
};
private onAction = (payload: ActionPayload) => {
switch (payload.action) {
case 'call_state': {
// listen for call state changes to prod the render method, which
// may hide the global CallView if the call it is tracking is dead
this.updateCalls();
break;
}
}
};
private updateCalls = () => {
private updateCalls = (): void => {
if (!this.state.roomId) return;
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(this.state.roomId);
@ -194,7 +182,7 @@ export default class CallPreview extends React.Component<IProps, IState> {
private onDoubleClick = (): void => {
dis.dispatch({
action: "view_room",
action: Action.ViewRoom,
room_id: this.state.primaryCall.roomId,
});
};

View file

@ -328,20 +328,17 @@ export default class CallView extends React.Component<IProps, IState> {
};
private onCallResumeClick = (): void => {
const userFacingRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call);
CallHandler.sharedInstance().setActiveCallRoomId(userFacingRoomId);
const userFacingRoomId = CallHandler.instance.roomIdForCall(this.props.call);
CallHandler.instance.setActiveCallRoomId(userFacingRoomId);
};
private onTransferClick = (): void => {
const transfereeCall = CallHandler.sharedInstance().getTransfereeForCallId(this.props.call.callId);
const transfereeCall = CallHandler.instance.getTransfereeForCallId(this.props.call.callId);
this.props.call.transferToCall(transfereeCall);
};
private onHangupClick = (): void => {
dis.dispatch({
action: 'hangup',
room_id: CallHandler.sharedInstance().roomIdForCall(this.props.call),
});
CallHandler.instance.hangupOrReject(CallHandler.instance.roomIdForCall(this.props.call));
};
private onToggleSidebar = (): void => {
@ -404,12 +401,12 @@ export default class CallView extends React.Component<IProps, IState> {
public render() {
const client = MatrixClientPeg.get();
const callRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call);
const secondaryCallRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.secondaryCall);
const callRoomId = CallHandler.instance.roomIdForCall(this.props.call);
const secondaryCallRoomId = CallHandler.instance.roomIdForCall(this.props.secondaryCall);
const callRoom = client.getRoom(callRoomId);
const secCallRoom = this.props.secondaryCall ? client.getRoom(secondaryCallRoomId) : null;
const avatarSize = this.props.pipMode ? 76 : 160;
const transfereeCall = CallHandler.sharedInstance().getTransfereeForCallId(this.props.call.callId);
const transfereeCall = CallHandler.instance.getTransfereeForCallId(this.props.call.callId);
const isOnHold = this.state.isLocalOnHold || this.state.isRemoteOnHold;
const isScreensharing = this.props.call.isScreensharing();
const sidebarShown = this.state.sidebarShown;
@ -423,12 +420,12 @@ export default class CallView extends React.Component<IProps, IState> {
if (transfereeCall) {
const transferTargetRoom = MatrixClientPeg.get().getRoom(
CallHandler.sharedInstance().roomIdForCall(this.props.call),
CallHandler.instance.roomIdForCall(this.props.call),
);
const transferTargetName = transferTargetRoom ? transferTargetRoom.name : _t("unknown person");
const transfereeRoom = MatrixClientPeg.get().getRoom(
CallHandler.sharedInstance().roomIdForCall(transfereeCall),
CallHandler.instance.roomIdForCall(transfereeCall),
);
const transfereeName = transfereeRoom ? transfereeRoom.name : _t("unknown person");
@ -449,7 +446,7 @@ export default class CallView extends React.Component<IProps, IState> {
} else if (isOnHold) {
let onHoldText = null;
if (this.state.isRemoteOnHold) {
const holdString = CallHandler.sharedInstance().hasAnyUnheldCall() ?
const holdString = CallHandler.instance.hasAnyUnheldCall() ?
_td("You held the call <a>Switch</a>") : _td("You held the call <a>Resume</a>");
onHoldText = _t(holdString, {}, {
a: sub => <AccessibleButton kind="link" onClick={this.onCallResumeClick}>

View file

@ -18,7 +18,6 @@ import { CallState, MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
import React from 'react';
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
import CallView from './CallView';
import dis from '../../../dispatcher/dispatcher';
import { Resizable } from "re-resizable";
import ResizeNotifier from "../../../utils/ResizeNotifier";
import { replaceableComponent } from "../../../utils/replaceableComponent";
@ -52,24 +51,15 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
}
public componentDidMount() {
this.dispatcherRef = dis.register(this.onAction);
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.updateCall);
CallHandler.instance.addListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
}
public componentWillUnmount() {
dis.unregister(this.dispatcherRef);
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
CallHandler.instance.removeListener(CallHandlerEvent.CallState, this.updateCall);
CallHandler.instance.removeListener(CallHandlerEvent.CallChangeRoom, this.updateCall);
}
private onAction = (payload) => {
switch (payload.action) {
case 'call_state': {
this.updateCall();
break;
}
}
};
private updateCall = () => {
const newCall = this.getCall();
if (newCall !== this.state.call) {
@ -78,7 +68,7 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
};
private getCall(): MatrixCall {
const call = CallHandler.sharedInstance().getCallForRoom(this.props.roomId);
const call = CallHandler.instance.getCallForRoom(this.props.roomId);
if (call && [CallState.Ended, CallState.Ringing].includes(call.state)) return null;
return call;

View file

@ -19,11 +19,9 @@ import { createRef } from "react";
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
import Field from "../elements/Field";
import DialPad from './DialPad';
import dis from '../../../dispatcher/dispatcher';
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { DialNumberPayload } from "../../../dispatcher/payloads/DialNumberPayload";
import { Action } from "../../../dispatcher/actions";
import DialPadBackspaceButton from "../elements/DialPadBackspaceButton";
import CallHandler from "../../../CallHandler";
interface IProps {
onFinished: (boolean) => void;
@ -81,12 +79,7 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
};
onDialPress = async () => {
const payload: DialNumberPayload = {
action: Action.DialNumber,
number: this.state.value,
};
dis.dispatch(payload);
CallHandler.instance.dialNumber(this.state.value);
this.props.onFinished(true);
};