Files
ThreadNet-Web/apps/web/src/toasts/IncomingLegacyCallToast.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

148 lines
5.5 KiB
TypeScript
Raw Normal View History

2021-07-24 13:05:14 +02:00
/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
2021-07-24 13:05:14 +02:00
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
2024-09-09 14:57:16 +01:00
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Copyright 2018 New Vector Ltd
Copyright 2015, 2016 OpenMarket Ltd
2021-07-24 13:05:14 +02:00
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
2024-09-09 14:57:16 +01:00
Please see LICENSE files in the repository root for full details.
2021-07-24 13:05:14 +02:00
*/
import React from "react";
2025-02-05 13:25:06 +00:00
import { CallType, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import {
EndCallIcon,
VideoCallSolidIcon,
VoiceCallSolidIcon,
VolumeOffSolidIcon,
VolumeOnSolidIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";
2021-10-22 17:23:32 -05:00
2026-07-07 13:29:54 +01:00
import { LegacyCallHandlerEvent } from "../LegacyCallHandler";
2021-07-24 13:05:14 +02:00
import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t } from "../languageHandler";
import RoomAvatar from "../components/views/avatars/RoomAvatar";
2025-02-05 13:25:06 +00:00
import AccessibleButton, { type ButtonEvent } from "../components/views/elements/AccessibleButton";
import { getCallStateIcon } from "../components/views/messages/LegacyCallEvent.tsx";
2026-07-07 13:29:54 +01:00
import { SDKContext } from "../contexts/SDKContext.ts";
2021-07-24 13:05:14 +02:00
export const getIncomingLegacyCallToastKey = (callId: string): string => `call_${callId}`;
2021-07-24 13:05:14 +02:00
interface IProps {
call: MatrixCall;
}
interface IState {
silenced: boolean;
}
export default class IncomingLegacyCallToast extends React.Component<IProps, IState> {
2026-07-07 13:29:54 +01:00
public static contextType = SDKContext;
declare public context: React.ContextType<typeof SDKContext>;
private readonly roomId: string;
2026-07-07 13:29:54 +01:00
public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
super(props, context);
2021-07-24 13:05:14 +02:00
2026-07-07 13:29:54 +01:00
const roomId = context.legacyCallHandler.roomIdForCall(this.props.call);
if (!roomId) {
throw new Error("Unable to find room for incoming call");
}
this.roomId = roomId;
2021-07-24 13:05:14 +02:00
this.state = {
2026-07-07 13:29:54 +01:00
silenced: context.legacyCallHandler.isCallSilenced(this.props.call.callId),
2021-07-24 13:05:14 +02:00
};
}
2021-07-26 10:34:59 +02:00
public componentDidMount = (): void => {
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.addListener(
LegacyCallHandlerEvent.SilencedCallsChanged,
this.onSilencedCallsChanged,
);
2021-07-24 13:05:14 +02:00
};
2021-07-25 08:06:11 +02:00
public componentWillUnmount(): void {
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.removeListener(
LegacyCallHandlerEvent.SilencedCallsChanged,
this.onSilencedCallsChanged,
);
2021-07-24 13:05:14 +02:00
}
2021-07-25 08:06:11 +02:00
private onSilencedCallsChanged = (): void => {
2026-07-07 13:29:54 +01:00
this.setState({ silenced: this.context.legacyCallHandler.isCallSilenced(this.props.call.callId) });
2021-07-24 13:05:14 +02:00
};
private onAnswerClick = (e: ButtonEvent): void => {
2021-07-24 13:05:14 +02:00
e.stopPropagation();
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.answerCall(this.roomId);
2021-07-24 13:05:14 +02:00
};
private onRejectClick = (e: ButtonEvent): void => {
2021-07-24 13:05:14 +02:00
e.stopPropagation();
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.hangupOrReject(this.roomId, true);
2021-07-24 13:05:14 +02:00
};
private onSilenceClick = (e: ButtonEvent): void => {
2021-07-24 13:05:14 +02:00
e.stopPropagation();
const callId = this.props.call.callId;
2024-10-16 16:43:07 +01:00
if (this.state.silenced) {
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.unSilenceCall(callId);
2024-10-16 16:43:07 +01:00
} else {
2026-07-07 13:29:54 +01:00
this.context.legacyCallHandler.silenceCall(callId);
2024-10-16 16:43:07 +01:00
}
2021-07-24 13:05:14 +02:00
};
public render(): React.ReactNode {
const room = MatrixClientPeg.safeGet().getRoom(this.roomId);
const isVoice = this.props.call.type === CallType.Voice;
2026-07-07 13:29:54 +01:00
const callForcedSilent = this.context.legacyCallHandler.isForcedSilent();
let silenceButtonTooltip = this.state.silenced ? _t("voip|unsilence") : _t("voip|silence");
if (callForcedSilent) {
silenceButtonTooltip = _t("voip|silenced");
}
2021-07-24 13:05:14 +02:00
return (
<React.Fragment>
<RoomAvatar room={room ?? undefined} size="32px" />
<div className="mx_IncomingLegacyCallToast_content">
<span className="mx_LegacyCallEvent_caller">{room ? room.name : _t("voip|unknown_caller")}</span>
<div className="mx_LegacyCallEvent_type">
{getCallStateIcon(isVoice, undefined)}
{isVoice ? _t("voip|voice_call") : _t("voip|video_call")}
2022-12-12 12:24:14 +01:00
</div>
<div className="mx_IncomingLegacyCallToast_buttons">
2021-07-24 14:04:22 +02:00
<AccessibleButton
className="mx_IncomingLegacyCallToast_button"
2021-07-24 14:04:22 +02:00
onClick={this.onRejectClick}
kind="danger"
2022-12-12 12:24:14 +01:00
>
<EndCallIcon />
{_t("action|decline")}
2021-07-24 14:04:22 +02:00
</AccessibleButton>
<AccessibleButton
className="mx_IncomingLegacyCallToast_button"
2021-07-24 14:04:22 +02:00
onClick={this.onAnswerClick}
kind="primary"
2022-12-12 12:24:14 +01:00
>
{isVoice ? <VoiceCallSolidIcon /> : <VideoCallSolidIcon />}
{_t("action|accept")}
2021-07-24 14:04:22 +02:00
</AccessibleButton>
2022-12-12 12:24:14 +01:00
</div>
2021-07-24 19:30:37 +02:00
</div>
<AccessibleButton
className="mx_IncomingLegacyCallToast_iconButton"
disabled={callForcedSilent}
2021-07-24 20:39:44 +02:00
onClick={this.onSilenceClick}
title={silenceButtonTooltip}
>
{this.state.silenced ? <VolumeOffSolidIcon /> : <VolumeOnSolidIcon />}
</AccessibleButton>
2021-07-24 13:05:14 +02:00
</React.Fragment>
);
}
}