From a33be00c08b37409c99f6d7b646c9233ba56e16f Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Dec 2020 14:59:06 +0000 Subject: [PATCH 1/2] 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 336b72cebf..3557976326 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 8ccbbe473c..5b936e822c 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 eb1d0a632e..5e4452a4bc 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", From 5aa8650fac441a71cd5e08ee3023c0d1be4a6851 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 15 Dec 2020 16:27:04 +0000 Subject: [PATCH 2/2] i18n --- src/i18n/strings/en_EN.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5e4452a4bc..3f05713ffe 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2070,6 +2070,8 @@ "We couldn't create your DM. Please check the users you want to invite and try again.": "We couldn't create your DM. Please check the users you want to invite and try again.", "Something went wrong trying to invite the users.": "Something went wrong trying to invite the users.", "We couldn't invite those users. Please check the users you want to invite and try again.": "We couldn't invite those users. Please check the users you want to invite and try again.", + "A call can only be transferred to a single user.": "A call can only be transferred to a single user.", + "Failed to transfer call": "Failed to transfer call", "Failed to find the following users": "Failed to find the following users", "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s", "Recent Conversations": "Recent Conversations", @@ -2083,6 +2085,7 @@ "Go": "Go", "Invite someone using their name, email address, username (like ) or share this room.": "Invite someone using their name, email address, username (like ) or share this room.", "Invite someone using their name, username (like ) or share this room.": "Invite someone using their name, username (like ) or share this room.", + "Transfer": "Transfer", "a new master key signature": "a new master key signature", "a new cross-signing key signature": "a new cross-signing key signature", "a device cross-signing signature": "a device cross-signing signature", @@ -2267,7 +2270,6 @@ "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",