Merge pull request #5494 from matrix-org/dbkr/call_transfer
Basic call transfer initiation support
This commit is contained in:
commit
470756546c
3 changed files with 58 additions and 1 deletions
|
@ -20,6 +20,8 @@ import { _t } from '../../../languageHandler';
|
||||||
import { ContextMenu, IProps as IContextMenuProps, MenuItem } from '../../structures/ContextMenu';
|
import { ContextMenu, IProps as IContextMenuProps, MenuItem } from '../../structures/ContextMenu';
|
||||||
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||||
import CallHandler from '../../../CallHandler';
|
import CallHandler from '../../../CallHandler';
|
||||||
|
import InviteDialog, { KIND_CALL_TRANSFER } from '../dialogs/InviteDialog';
|
||||||
|
import Modal from '../../../Modal';
|
||||||
|
|
||||||
interface IProps extends IContextMenuProps {
|
interface IProps extends IContextMenuProps {
|
||||||
call: MatrixCall;
|
call: MatrixCall;
|
||||||
|
@ -46,14 +48,30 @@ export default class CallContextMenu extends React.Component<IProps> {
|
||||||
this.props.onFinished();
|
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() {
|
render() {
|
||||||
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
|
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
|
||||||
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;
|
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;
|
||||||
|
|
||||||
|
let transferItem;
|
||||||
|
if (this.props.call.opponentCanBeTransferred()) {
|
||||||
|
transferItem = <MenuItem className="mx_CallContextMenu_item" onClick={this.onTransferClick}>
|
||||||
|
{_t("Transfer")}
|
||||||
|
</MenuItem>;
|
||||||
|
}
|
||||||
|
|
||||||
return <ContextMenu {...this.props}>
|
return <ContextMenu {...this.props}>
|
||||||
<MenuItem className="mx_CallContextMenu_item" onClick={handler}>
|
<MenuItem className="mx_CallContextMenu_item" onClick={handler}>
|
||||||
{holdUnholdCaption}
|
{holdUnholdCaption}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
{transferItem}
|
||||||
</ContextMenu>;
|
</ContextMenu>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,14 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import {UIFeature} from "../../../settings/UIFeature";
|
import {UIFeature} from "../../../settings/UIFeature";
|
||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
import {Room} from "matrix-js-sdk/src/models/room";
|
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.
|
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
export const KIND_DM = "dm";
|
export const KIND_DM = "dm";
|
||||||
export const KIND_INVITE = "invite";
|
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 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
|
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.
|
// The room ID this dialog is for. Only required for KIND_INVITE.
|
||||||
roomId: string,
|
roomId: string,
|
||||||
|
|
||||||
|
// The call to transfer. Only required for KIND_CALL_TRANSFER.
|
||||||
|
call: MatrixCall,
|
||||||
|
|
||||||
// Initial value to populate the filter with
|
// Initial value to populate the filter with
|
||||||
initialText: string,
|
initialText: string,
|
||||||
}
|
}
|
||||||
|
@ -345,6 +350,8 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
|
|
||||||
if (props.kind === KIND_INVITE && !props.roomId) {
|
if (props.kind === KIND_INVITE && !props.roomId) {
|
||||||
throw new Error("When using KIND_INVITE a roomId is required for an InviteDialog");
|
throw new Error("When using KIND_INVITE a roomId is required for an InviteDialog");
|
||||||
|
} else if (props.kind === KIND_CALL_TRANSFER && !props.call) {
|
||||||
|
throw new Error("When using KIND_CALL_TRANSFER a call is required for an InviteDialog");
|
||||||
}
|
}
|
||||||
|
|
||||||
const alreadyInvited = new Set([MatrixClientPeg.get().getUserId(), SdkConfig.get()['welcomeUserId']]);
|
const alreadyInvited = new Set([MatrixClientPeg.get().getUserId(), SdkConfig.get()['welcomeUserId']]);
|
||||||
|
@ -702,6 +709,29 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_transferCall = async () => {
|
||||||
|
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) => {
|
_onKeyDown = (e) => {
|
||||||
if (this.state.busy) return;
|
if (this.state.busy) return;
|
||||||
const value = e.target.value.trim();
|
const value = e.target.value.trim();
|
||||||
|
@ -1217,7 +1247,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
}
|
}
|
||||||
buttonText = _t("Go");
|
buttonText = _t("Go");
|
||||||
goButtonFn = this._startDm;
|
goButtonFn = this._startDm;
|
||||||
} else { // KIND_INVITE
|
} else if (this.props.kind === KIND_INVITE) {
|
||||||
title = _t("Invite to this room");
|
title = _t("Invite to this room");
|
||||||
|
|
||||||
if (identityServersEnabled) {
|
if (identityServersEnabled) {
|
||||||
|
@ -1251,6 +1281,12 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
|
|
||||||
buttonText = _t("Invite");
|
buttonText = _t("Invite");
|
||||||
goButtonFn = this._inviteUsers;
|
goButtonFn = this._inviteUsers;
|
||||||
|
} else if (this.props.kind === KIND_CALL_TRANSFER) {
|
||||||
|
title = _t("Transfer");
|
||||||
|
buttonText = _t("Transfer");
|
||||||
|
goButtonFn = this._transferCall;
|
||||||
|
} else {
|
||||||
|
console.error("Unknown kind of InviteDialog: " + this.props.kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasSelection = this.state.targets.length > 0
|
const hasSelection = this.state.targets.length > 0
|
||||||
|
|
|
@ -2077,6 +2077,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.",
|
"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.",
|
"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.",
|
"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",
|
"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",
|
"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",
|
"Recent Conversations": "Recent Conversations",
|
||||||
|
@ -2090,6 +2092,7 @@
|
||||||
"Go": "Go",
|
"Go": "Go",
|
||||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.",
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.",
|
||||||
"Invite someone using their name, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this room</a>.",
|
"Invite someone using their name, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this room</a>.",
|
||||||
|
"Transfer": "Transfer",
|
||||||
"a new master key signature": "a new master key signature",
|
"a new master key signature": "a new master key signature",
|
||||||
"a new cross-signing key signature": "a new cross-signing key signature",
|
"a new cross-signing key signature": "a new cross-signing key signature",
|
||||||
"a device cross-signing signature": "a device cross-signing signature",
|
"a device cross-signing signature": "a device cross-signing signature",
|
||||||
|
|
Loading…
Reference in a new issue