Update report room dialog to match designs (#29669)

* Rework for designs

* Update report room position

* lint

* Improve test coverage
This commit is contained in:
Will Hunt
2025-04-03 14:25:19 +01:00
committed by GitHub
parent 1f9db9fa1a
commit cb657d6848
11 changed files with 280 additions and 186 deletions

View File

@@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details.
*/
import React, { type JSX, type ChangeEventHandler, useCallback, useState } from "react";
import { Root, Field, Label, InlineSpinner, ErrorMessage } from "@vector-im/compound-web";
import { Root, Field, Label, InlineSpinner, ErrorMessage, HelpMessage } from "@vector-im/compound-web";
import { _t } from "../../../languageHandler";
import SdkConfig from "../../../SdkConfig";
@@ -14,10 +14,11 @@ import Markdown from "../../../Markdown";
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
interface IProps {
roomId: string;
onFinished(complete: boolean): void;
onFinished(leave: boolean): void;
}
/*
@@ -27,27 +28,26 @@ interface IProps {
export const ReportRoomDialog: React.FC<IProps> = function ({ roomId, onFinished }) {
const [error, setErr] = useState<string>();
const [busy, setBusy] = useState(false);
const [sent, setSent] = useState(false);
const [reason, setReason] = useState("");
const [leaveRoom, setLeaveRoom] = useState(false);
const client = MatrixClientPeg.safeGet();
const onReasonChange = useCallback<ChangeEventHandler<HTMLTextAreaElement>>((e) => setReason(e.target.value), []);
const onCancel = useCallback(() => onFinished(sent), [sent, onFinished]);
const onCancel = useCallback(() => onFinished(false), [onFinished]);
const onSubmit = useCallback(async () => {
setBusy(true);
try {
await client.reportRoom(roomId, reason);
setSent(true);
onFinished(leaveRoom);
} catch (ex) {
setBusy(false);
if (ex instanceof Error) {
setErr(ex.message);
} else {
setErr("Unknown error");
}
} finally {
setBusy(false);
}
}, [roomId, reason, client]);
}, [roomId, reason, client, leaveRoom, onFinished]);
const adminMessageMD = SdkConfig.getObject("report_event")?.get("admin_message_md", "adminMessageMD");
let adminMessage: JSX.Element | undefined;
@@ -59,37 +59,39 @@ export const ReportRoomDialog: React.FC<IProps> = function ({ roomId, onFinished
return (
<BaseDialog
className="mx_ReportRoomDialog"
onFinished={() => onFinished(sent)}
title={_t("report_room|title")}
onFinished={onCancel}
title={_t("action|report_room")}
contentId="mx_ReportEventDialog"
>
{sent && <p>{_t("report_room|sent")}</p>}
{!sent && (
<Root id="mx_ReportEventDialog" onSubmit={onSubmit}>
<p>{_t("report_room|description")}</p>
{adminMessage}
<Field name="reason">
<Label htmlFor="mx_ReportRoomDialog_reason">{_t("room_settings|permissions|ban_reason")}</Label>
<textarea
id="mx_ReportRoomDialog_reason"
placeholder={_t("report_room|reason_placeholder")}
rows={5}
onChange={onReasonChange}
value={reason}
disabled={busy}
/>
{error ? <ErrorMessage>{error}</ErrorMessage> : null}
</Field>
{busy ? <InlineSpinner /> : null}
<DialogButtons
primaryButton={_t("action|send_report")}
onPrimaryButtonClick={onSubmit}
focus={true}
onCancel={onCancel}
<Root id="mx_ReportEventDialog" onSubmit={onSubmit}>
<Field name="reason">
<Label htmlFor="mx_ReportRoomDialog_reason">{_t("report_room|reason_label")}</Label>
<textarea
id="mx_ReportRoomDialog_reason"
rows={5}
onChange={onReasonChange}
value={reason}
disabled={busy}
/>
</Root>
)}
{error ? <ErrorMessage>{error}</ErrorMessage> : null}
<HelpMessage>{_t("report_room|description")}</HelpMessage>
</Field>
{adminMessage}
{busy ? <InlineSpinner /> : null}
<LabelledToggleSwitch
label={_t("room_list|more_options|leave_room")}
value={leaveRoom}
onChange={setLeaveRoom}
/>
<DialogButtons
primaryButton={_t("action|send_report")}
onPrimaryButtonClick={onSubmit}
focus={true}
onCancel={onCancel}
primaryButtonClass="danger"
primaryDisabled={busy || !reason}
/>
</Root>
</BaseDialog>
);
};

View File

@@ -233,10 +233,16 @@ const RoomSummaryCard: React.FC<IProps> = ({
room_id: room.roomId,
});
};
const onReportRoomClick = (): void => {
Modal.createDialog(ReportRoomDialog, {
const onReportRoomClick = async (): Promise<void> => {
const [leave] = await Modal.createDialog(ReportRoomDialog, {
roomId: room.roomId,
});
}).finished;
if (leave) {
defaultDispatcher.dispatch({
action: "leave_room",
room_id: room.roomId,
});
}
};
const isRoomEncrypted = useIsEncrypted(cli, room);
@@ -447,6 +453,12 @@ const RoomSummaryCard: React.FC<IProps> = ({
<Separator />
<div className="mx_RoomSummaryCard_bottomOptions">
<MenuItem
Icon={ErrorIcon}
kind="critical"
label={_t("action|report_room")}
onSelect={onReportRoomClick}
/>
<MenuItem
className="mx_RoomSummaryCard_leave"
Icon={LeaveIcon}
@@ -454,12 +466,6 @@ const RoomSummaryCard: React.FC<IProps> = ({
label={_t("action|leave_room")}
onSelect={onLeaveRoomClick}
/>
<MenuItem
Icon={ErrorIcon}
kind="critical"
label={_t("action|report_room")}
onSelect={onReportRoomClick}
/>
</div>
</div>
</BaseCard>