From a33be00c08b37409c99f6d7b646c9233ba56e16f Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Dec 2020 14:59:06 +0000 Subject: [PATCH] Basic call transfer initiation support Adapt the InviteDialog to select a transfer target Doesn't support supplying a roo mID fr the transfer: just leaves the transferee to work out how to contact the target themselves. MSC2747 (matrix-org/matrix-doc#2747) Requires https://github.com/matrix-org/matrix-js-sdk/pull/1558 --- .../views/context_menus/CallContextMenu.tsx | 18 +++++++++ src/components/views/dialogs/InviteDialog.tsx | 38 ++++++++++++++++++- src/i18n/strings/en_EN.json | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/components/views/context_menus/CallContextMenu.tsx b/src/components/views/context_menus/CallContextMenu.tsx index 336b72cebfc..35579763260 100644 --- a/src/components/views/context_menus/CallContextMenu.tsx +++ b/src/components/views/context_menus/CallContextMenu.tsx @@ -20,6 +20,8 @@ import { _t } from '../../../languageHandler'; import { ContextMenu, IProps as IContextMenuProps, MenuItem } from '../../structures/ContextMenu'; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import CallHandler from '../../../CallHandler'; +import InviteDialog, { KIND_CALL_TRANSFER } from '../dialogs/InviteDialog'; +import Modal from '../../../Modal'; interface IProps extends IContextMenuProps { call: MatrixCall; @@ -46,14 +48,30 @@ export default class CallContextMenu extends React.Component { this.props.onFinished(); } + onTransferClick = () => { + Modal.createTrackedDialog( + 'Transfer Call', '', InviteDialog, {kind: KIND_CALL_TRANSFER, call: this.props.call}, + /*className=*/null, /*isPriority=*/false, /*isStatic=*/true, + ); + this.props.onFinished(); + } + render() { const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold"); const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick; + let transferItem; + if (this.props.call.opponentCanBeTransferred()) { + transferItem = + {_t("Transfer")} + ; + } + return {holdUnholdCaption} + {transferItem} ; } } diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 8ccbbe473cb..5b936e822c6 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -41,12 +41,14 @@ import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; import CountlyAnalytics from "../../../CountlyAnalytics"; import {Room} from "matrix-js-sdk/src/models/room"; +import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; // we have a number of types defined from the Matrix spec which can't reasonably be altered here. /* eslint-disable camelcase */ export const KIND_DM = "dm"; export const KIND_INVITE = "invite"; +export const KIND_CALL_TRANSFER = "call_transfer"; const INITIAL_ROOMS_SHOWN = 3; // Number of rooms to show at first const INCREMENT_ROOMS_SHOWN = 5; // Number of rooms to add when 'show more' is clicked @@ -310,6 +312,9 @@ interface IInviteDialogProps { // The room ID this dialog is for. Only required for KIND_INVITE. roomId: string, + // The call to transfer. Only required for KIND_CALL_TRANSFER. + call: MatrixCall, + // Initial value to populate the filter with initialText: string, } @@ -345,6 +350,8 @@ export default class InviteDialog extends React.PureComponent { + this._convertFilter(); + const targets = this._convertFilter(); + const targetIds = targets.map(t => t.userId); + if (targetIds.length > 1) { + this.setState({ + errorText: _t("A call can only be transferred to a single user."), + }); + } + + this.setState({busy: true}); + try { + await this.props.call.transfer(targetIds[0]); + this.setState({busy: false}); + this.props.onFinished(); + } catch (e) { + this.setState({ + busy: false, + errorText: _t("Failed to transfer call"), + }); + } + }; + _onKeyDown = (e) => { if (this.state.busy) return; const value = e.target.value.trim(); @@ -1217,7 +1247,7 @@ export default class InviteDialog extends React.PureComponent 0 diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index eb1d0a632e7..5e4452a4bc2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2267,6 +2267,7 @@ "If you've forgotten your recovery key you can ": "If you've forgotten your recovery key you can ", "Resume": "Resume", "Hold": "Hold", + "Transfer": "Transfer", "Reject invitation": "Reject invitation", "Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?", "Unable to reject invite": "Unable to reject invite",