diff --git a/src/components/views/messages/CallEvent.tsx b/src/components/views/messages/CallEvent.tsx index df903196b8..02602cf334 100644 --- a/src/components/views/messages/CallEvent.tsx +++ b/src/components/views/messages/CallEvent.tsx @@ -168,7 +168,7 @@ export const CallEvent = forwardRef(({ mxEvent }, ref) => { .getRoom(mxEvent.getRoomId())! .currentState.getStateEvents(mxEvent.getType(), mxEvent.getStateKey()!)!; - if ("m.terminated" in latestEvent.getContent()) { + if ("m.terminated" in latestEvent.getContent() || latestEvent.isRedacted()) { // The call is terminated return (
diff --git a/src/toasts/IncomingCallToast.tsx b/src/toasts/IncomingCallToast.tsx index e3e1b84dda..72df4fd122 100644 --- a/src/toasts/IncomingCallToast.tsx +++ b/src/toasts/IncomingCallToast.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React, { useCallback, useEffect } from "react"; -import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event"; import { _t } from "../languageHandler"; import RoomAvatar from "../components/views/avatars/RoomAvatar"; @@ -36,6 +36,7 @@ import { ButtonEvent } from "../components/views/elements/AccessibleButton"; import { useDispatcher } from "../hooks/useDispatcher"; import { ActionPayload } from "../dispatcher/payloads"; import { Call } from "../models/Call"; +import { useTypedEventEmitter } from "../hooks/useEventEmitter"; export const getIncomingCallToastKey = (stateKey: string): string => `call_${stateKey}`; @@ -89,6 +90,8 @@ export function IncomingCallToast({ callEvent }: Props): JSX.Element { } }, [latestEvent, dismissToast]); + useTypedEventEmitter(latestEvent, MatrixEventEvent.BeforeRedaction, dismissToast); + useDispatcher( defaultDispatcher, useCallback( diff --git a/test/components/views/messages/CallEvent-test.tsx b/test/components/views/messages/CallEvent-test.tsx index c1f04e8978..7d10a35b8d 100644 --- a/test/components/views/messages/CallEvent-test.tsx +++ b/test/components/views/messages/CallEvent-test.tsx @@ -114,6 +114,14 @@ describe("CallEvent", () => { screen.getByText("1m 30s"); }); + it("shows a message if the call was redacted", () => { + const event = room.currentState.getStateEvents(MockedCall.EVENT_TYPE, "1")!; + jest.spyOn(event, "isRedacted").mockReturnValue(true); + renderEvent(); + + screen.getByText("Video call ended"); + }); + it("shows placeholder info if the call isn't loaded yet", () => { jest.spyOn(CallStore.instance, "getCall").mockReturnValue(null); jest.advanceTimersByTime(90000); diff --git a/test/toasts/IncomingCallToast-test.tsx b/test/toasts/IncomingCallToast-test.tsx index 212042949e..33b9c94609 100644 --- a/test/toasts/IncomingCallToast-test.tsx +++ b/test/toasts/IncomingCallToast-test.tsx @@ -21,6 +21,7 @@ import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state"; import { ClientWidgetApi, Widget } from "matrix-widget-api"; +import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event"; import type { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { @@ -176,4 +177,15 @@ describe("IncomingCallEvent", () => { expect(toastStore.dismissToast).toHaveBeenCalledWith(getIncomingCallToastKey(call.event.getStateKey()!)), ); }); + + it("closes toast when the call event is redacted", async () => { + renderToast(); + + const event = room.currentState.getStateEvents(MockedCall.EVENT_TYPE, "1")!; + event.emit(MatrixEventEvent.BeforeRedaction, event, {} as unknown as MatrixEvent); + + await waitFor(() => + expect(toastStore.dismissToast).toHaveBeenCalledWith(getIncomingCallToastKey(call.event.getStateKey()!)), + ); + }); });