Files
ThreadNet-Web/src/toasts/IncomingLegacyCallToast.tsx
T
Michael TelatynskiandGitHub 466f60ead5 Update the way we render icons for accessibility (#31731)
* Switch to Compound icons to replace old icons

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Apply same treatment to missed icons

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove duplicated icon

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update icon

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in ImageView

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in ExtensionsCard

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in LegacyRoomListHeader

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in ImageSizePanel

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in LegacyRoomList

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove icon from CreateSecretStorageDialog title

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in LiveContentSummary

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in RoomCallBanner

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in NonUrgentEchoFailureToast

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in LegacyCallViewHeader

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Switch from css masks to rendering svg in CallEvent

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Delint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update screenshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Replace dark-light-mode.svg with Compound

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Draw stop icon using svg rather than square mask

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Replace masks in RoomSublist with SVG icons

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Replace masks with SVG icons in LegacyCall views

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Replace masks with SVG icons in EventTile

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Replace masks with SVG icons in ForwardDialog

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove redundant css style

The `::before` has no content so is never rendered

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* delint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update playwright tests & screenshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshot

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Remove snapshot as it causes issues

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Delint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* More tests

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2026-01-16 11:21:57 +00:00

141 lines
5.3 KiB
TypeScript

/*
Copyright 2024 New Vector Ltd.
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Copyright 2018 New Vector Ltd
Copyright 2015, 2016 OpenMarket Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { CallType, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import classNames from "classnames";
import { VolumeOffSolidIcon, VolumeOnSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import LegacyCallHandler, { LegacyCallHandlerEvent } from "../LegacyCallHandler";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t } from "../languageHandler";
import RoomAvatar from "../components/views/avatars/RoomAvatar";
import AccessibleButton, { type ButtonEvent } from "../components/views/elements/AccessibleButton";
export const getIncomingLegacyCallToastKey = (callId: string): string => `call_${callId}`;
interface IProps {
call: MatrixCall;
}
interface IState {
silenced: boolean;
}
export default class IncomingLegacyCallToast extends React.Component<IProps, IState> {
private readonly roomId: string;
public constructor(props: IProps) {
super(props);
const roomId = LegacyCallHandler.instance.roomIdForCall(this.props.call);
if (!roomId) {
throw new Error("Unable to find room for incoming call");
}
this.roomId = roomId;
this.state = {
silenced: LegacyCallHandler.instance.isCallSilenced(this.props.call.callId),
};
}
public componentDidMount = (): void => {
LegacyCallHandler.instance.addListener(
LegacyCallHandlerEvent.SilencedCallsChanged,
this.onSilencedCallsChanged,
);
};
public componentWillUnmount(): void {
LegacyCallHandler.instance.removeListener(
LegacyCallHandlerEvent.SilencedCallsChanged,
this.onSilencedCallsChanged,
);
}
private onSilencedCallsChanged = (): void => {
this.setState({ silenced: LegacyCallHandler.instance.isCallSilenced(this.props.call.callId) });
};
private onAnswerClick = (e: ButtonEvent): void => {
e.stopPropagation();
LegacyCallHandler.instance.answerCall(this.roomId);
};
private onRejectClick = (e: ButtonEvent): void => {
e.stopPropagation();
LegacyCallHandler.instance.hangupOrReject(this.roomId, true);
};
private onSilenceClick = (e: ButtonEvent): void => {
e.stopPropagation();
const callId = this.props.call.callId;
if (this.state.silenced) {
LegacyCallHandler.instance.unSilenceCall(callId);
} else {
LegacyCallHandler.instance.silenceCall(callId);
}
};
public render(): React.ReactNode {
const room = MatrixClientPeg.safeGet().getRoom(this.roomId);
const isVoice = this.props.call.type === CallType.Voice;
const callForcedSilent = LegacyCallHandler.instance.isForcedSilent();
let silenceButtonTooltip = this.state.silenced ? _t("voip|unsilence") : _t("voip|silence");
if (callForcedSilent) {
silenceButtonTooltip = _t("voip|silenced");
}
const contentClass = classNames("mx_IncomingLegacyCallToast_content", {
mx_IncomingLegacyCallToast_content_voice: isVoice,
mx_IncomingLegacyCallToast_content_video: !isVoice,
});
return (
<React.Fragment>
<RoomAvatar room={room ?? undefined} size="32px" />
<div className={contentClass}>
<span className="mx_LegacyCallEvent_caller">{room ? room.name : _t("voip|unknown_caller")}</span>
<div className="mx_LegacyCallEvent_type">
<div className="mx_LegacyCallEvent_type_icon" />
{isVoice ? _t("voip|voice_call") : _t("voip|video_call")}
</div>
<div className="mx_IncomingLegacyCallToast_buttons">
<AccessibleButton
className="mx_IncomingLegacyCallToast_button mx_IncomingLegacyCallToast_button_decline"
onClick={this.onRejectClick}
kind="danger"
>
<span> {_t("action|decline")} </span>
</AccessibleButton>
<AccessibleButton
className="mx_IncomingLegacyCallToast_button mx_IncomingLegacyCallToast_button_accept"
onClick={this.onAnswerClick}
kind="primary"
>
<span> {_t("action|accept")} </span>
</AccessibleButton>
</div>
</div>
<AccessibleButton
className="mx_IncomingLegacyCallToast_iconButton"
disabled={callForcedSilent}
onClick={this.onSilenceClick}
title={silenceButtonTooltip}
>
{this.state.silenced ? <VolumeOffSolidIcon /> : <VolumeOnSolidIcon />}
</AccessibleButton>
</React.Fragment>
);
}
}