Apply review suggestions

This commit is contained in:
Jaiwanth 2021-08-13 23:44:07 +05:30
parent c62210b07c
commit 7207329c15
14 changed files with 201 additions and 195 deletions

View file

@ -36,7 +36,6 @@ interface IProps extends Omit<React.ComponentProps<typeof BaseAvatar>, "name" |
// Whether the onClick of the avatar should be overridden to dispatch `Action.ViewUser`
viewUserOnClick?: boolean;
title?: string;
forExport?: boolean;
}
interface IState {
@ -90,8 +89,7 @@ export default class MemberAvatar extends React.Component<IProps, IState> {
}
render() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
let { member, fallbackUserId, onClick, viewUserOnClick, forExport, ...otherProps } = this.props;
let { member, fallbackUserId, onClick, viewUserOnClick, ...otherProps } = this.props;
const userId = member ? member.userId : fallbackUserId;
if (viewUserOnClick) {

View file

@ -29,13 +29,15 @@ import {
textForFormat,
textForType,
} from "../../../utils/exportUtils/exportUtils";
import { IFieldState, IValidationResult } from "../elements/Validation";
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
import HTMLExporter from "../../../utils/exportUtils/HtmlExport";
import JSONExporter from "../../../utils/exportUtils/JSONExport";
import PlainTextExporter from "../../../utils/exportUtils/PlainTextExport";
import { useStateCallback } from "../../../hooks/useStateCallback";
import Exporter from "../../../utils/exportUtils/Exporter";
import Spinner from "../elements/Spinner";
import Modal from "../../../Modal";
import InfoDialog from "./InfoDialog";
interface IProps extends IDialogProps {
room: Room;
@ -126,67 +128,85 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
await startExport();
};
const onValidateSize = async ({
value,
}: Pick<IFieldState, "value">): Promise<IValidationResult> => {
const parsedSize = parseFloat(value);
const min = 1;
const max = 2000;
const validateSize = withValidation({
rules: [
{
key: "required",
test({ value, allowEmpty }) {
return allowEmpty || !!value;
},
invalid: () => {
const min = 1;
const max = 10 ** 8;
return _t("Enter a number between %(min)s and %(max)s", {
min,
max,
});
},
}, {
key: "number",
test: ({ value }) => {
const parsedSize = parseFloat(value);
const min = 1;
const max = 2000;
return !(isNaN(parsedSize) || min > parsedSize || parsedSize > max);
},
invalid: () => {
const min = 1;
const max = 2000;
return _t(
"Size can only be a number between %(min)s MB and %(max)s MB",
{ min, max },
);
},
},
],
});
if (isNaN(parsedSize)) {
return { valid: false, feedback: _t("Size must be a number") };
}
if (min > parsedSize || parsedSize > max) {
return {
valid: false,
feedback: _t(
"Size can only be between %(min)s MB and %(max)s MB",
{ min, max },
),
};
}
return {
valid: true,
feedback: _t("Enter size between %(min)s MB and %(max)s MB", {
min,
max,
}),
};
const onValidateSize = async (fieldState: IFieldState): Promise<IValidationResult> => {
const result = await validateSize(fieldState);
return result;
};
const onValidateNumberOfMessages = async ({
value,
}: Pick<IFieldState, "value">): Promise<IValidationResult> => {
const parsedSize = parseFloat(value);
const min = 1;
const max = 10 ** 8;
const validateNumberOfMessages = withValidation({
rules: [
{
key: "required",
test({ value, allowEmpty }) {
return allowEmpty || !!value;
},
invalid: () => {
const min = 1;
const max = 10 ** 8;
return _t("Enter a number between %(min)s and %(max)s", {
min,
max,
});
},
}, {
key: "number",
test: ({ value }) => {
const parsedSize = parseFloat(value);
const min = 1;
const max = 10 ** 8;
if (isNaN(parsedSize)) return false;
return !(min > parsedSize || parsedSize > max);
},
invalid: () => {
const min = 1;
const max = 10 ** 8;
return _t(
"Number of messages can only be a number between %(min)s and %(max)s",
{ min, max },
);
},
},
],
});
if (isNaN(parsedSize)) {
return {
valid: false,
feedback: _t("Number of messages must be a number"),
};
}
if (min > parsedSize || parsedSize > max) {
return {
valid: false,
feedback: _t(
"Number of messages can only be between %(min)s and %(max)s",
{ min, max },
),
};
}
return {
valid: true,
feedback: _t("Enter a number between %(min)s and %(max)s", {
min,
max,
}),
};
const onValidateNumberOfMessages = async (fieldState: IFieldState): Promise<IValidationResult> => {
const result = await validateNumberOfMessages(fieldState);
return result;
};
const onCancel = async () => {
@ -236,42 +256,20 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
if (exportCancelled) {
// Display successful cancellation message
return (
<BaseDialog
title={_t("Export Cancelled")}
className="mx_ExportDialog"
contentId="mx_Dialog_content"
onFinished={onFinished}
fixedWidth={true}
>
<p>{ _t("The export was cancelled successfully") }</p>
<DialogButtons
primaryButton={_t("Okay")}
hasCancel={false}
onPrimaryButtonClick={onFinished}
/>
</BaseDialog>
);
Modal.createTrackedDialog("Export Cancelled", "", InfoDialog, {
title: _t("Export Cancelled"),
description: <p>{ _t("The export was cancelled successfully") }</p>,
hasCloseButton: true,
});
return null;
} else if (exportSuccessful) {
// Display successful export message
return (
<BaseDialog
title={_t("Export Successful")}
className="mx_ExportDialog"
contentId="mx_Dialog_content"
onFinished={onFinished}
fixedWidth={true}
>
<p>{ _t("Your messages were successfully exported") }</p>
<DialogButtons
primaryButton={_t("Okay")}
hasCancel={false}
onPrimaryButtonClick={onFinished}
/>
</BaseDialog>
);
Modal.createTrackedDialog("Export Successful", "", InfoDialog, {
title: _t("Export Successful"),
description: <p>{ _t("Your messages were successfully exported") }</p>,
hasCloseButton: true,
});
return null;
} else if (displayCancel) {
// Display cancel warning
return (

View file

@ -355,10 +355,10 @@ export default class ReplyThread extends React.Component<IProps, IState> {
} else if (this.props.forExport) {
const eventId = ReplyThread.getParentEventId(this.props.parentEv);
header = <p className="mx_ReplyThread_Export">
{ _t("In reply to <messageLink/>",
{ _t("In reply to <a>this message</a>",
{},
{ messageLink: () => (
<a className="mx_reply_anchor" href={`#${eventId}`} scroll-to={eventId}> { _t("this message") } </a>
{ a: (sub) => (
<a className="mx_reply_anchor" href={`#${eventId}`} scroll-to={eventId}> { sub } </a>
),
})
}

View file

@ -47,7 +47,7 @@ export default class CallEvent extends React.Component<IProps, IState> {
super(props);
this.state = {
callState: this.props.callEventGrouper?.state,
callState: this.props.callEventGrouper.state,
silenced: false,
};
}
@ -210,7 +210,7 @@ export default class CallEvent extends React.Component<IProps, IState> {
render() {
const event = this.props.mxEvent;
const sender = event.sender ? event.sender.name : event.getSender();
const isVoice = this.props.callEventGrouper?.isVoice;
const isVoice = this.props.callEventGrouper.isVoice;
const callType = isVoice ? _t("Voice call") : _t("Video call");
const callState = this.state.callState;
const hangupReason = this.props.callEventGrouper.hangupReason;

View file

@ -201,11 +201,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
if (this.props.showGenericPlaceholder) {
placeholder = (
<AccessibleButton className="mx_MediaBody mx_MFileBody_info" onClick={this.onPlaceholderClick}>
<span className="mx_MFileBody_info_icon">
{ this.props.forExport ?
<img alt="Attachment" className="mx_export_attach_icon" src="icons/attach.svg" />
: null }
</span>
<span className="mx_MFileBody_info_icon" />
<TextWithTooltip tooltip={presentableTextForFile(this.content, _t("Attachment"), true)}>
<span className="mx_MFileBody_info_filename">
{ presentableTextForFile(this.content, _t("Attachment"), true, true) }

View file

@ -39,7 +39,6 @@ const RedactedBody = React.forwardRef<any, IBodyProps>(({ mxEvent, forExport },
return (
<span className="mx_RedactedBody" ref={ref} title={titleText}>
{ forExport ? <img alt={_t("Redacted")} className="mx_export_trash_icon" src="icons/trash.svg" /> : null }
{ text }
</span>
);