Convert EditHistoryMessage to TS

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
pull/21833/head
Šimon Brandner 2021-09-24 19:55:52 +02:00
parent 0354a7025d
commit bee85a0bcd
No known key found for this signature in database
GPG Key ID: 55C211A1226CB17D
2 changed files with 53 additions and 39 deletions

View File

@ -15,107 +15,112 @@ limitations under the License.
*/ */
import React, { createRef } from 'react'; import React, { createRef } from 'react';
import PropTypes from 'prop-types';
import * as HtmlUtils from '../../../HtmlUtils'; import * as HtmlUtils from '../../../HtmlUtils';
import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils'; import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils';
import { formatTime } from '../../../DateUtils'; import { formatTime } from '../../../DateUtils';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event'; import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { pillifyLinks, unmountPills } from '../../../utils/pillify'; import { pillifyLinks, unmountPills } from '../../../utils/pillify';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import * as sdk from '../../../index';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import classNames from 'classnames'; import classNames from 'classnames';
import RedactedBody from "./RedactedBody"; import RedactedBody from "./RedactedBody";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AccessibleButton from "../elements/AccessibleButton";
import ConfirmAndWaitRedactDialog from "../dialogs/ConfirmAndWaitRedactDialog";
import ViewSource from "../../structures/ViewSource";
function getReplacedContent(event) { function getReplacedContent(event) {
const originalContent = event.getOriginalContent(); const originalContent = event.getOriginalContent();
return originalContent["m.new_content"] || originalContent; return originalContent["m.new_content"] || originalContent;
} }
@replaceableComponent("views.messages.EditHistoryMessage") interface IProps {
export default class EditHistoryMessage extends React.PureComponent { // the message event being edited
static propTypes = { mxEvent: MatrixEvent;
// the message event being edited previousEdit?: MatrixEvent;
mxEvent: PropTypes.instanceOf(MatrixEvent).isRequired, isBaseEvent?: boolean;
previousEdit: PropTypes.instanceOf(MatrixEvent), isTwelveHour?: boolean;
isBaseEvent: PropTypes.bool, }
};
constructor(props) { interface IState {
canRedact: boolean;
sendStatus: EventStatus;
}
@replaceableComponent("views.messages.EditHistoryMessage")
export default class EditHistoryMessage extends React.PureComponent<IProps, IState> {
private content = createRef<HTMLDivElement>();
private pills: Element[] = [];
constructor(props: IProps) {
super(props); super(props);
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const { userId } = cli.credentials; const { userId } = cli.credentials;
const event = this.props.mxEvent; const event = this.props.mxEvent;
const room = cli.getRoom(event.getRoomId()); const room = cli.getRoom(event.getRoomId());
if (event.localRedactionEvent()) { if (event.localRedactionEvent()) {
event.localRedactionEvent().on("status", this._onAssociatedStatusChanged); event.localRedactionEvent().on("status", this.onAssociatedStatusChanged);
} }
const canRedact = room.currentState.maySendRedactionForEvent(event, userId); const canRedact = room.currentState.maySendRedactionForEvent(event, userId);
this.state = { canRedact, sendStatus: event.getAssociatedStatus() }; this.state = { canRedact, sendStatus: event.getAssociatedStatus() };
this._content = createRef();
this._pills = [];
} }
_onAssociatedStatusChanged = () => { private onAssociatedStatusChanged = (): void => {
this.setState({ sendStatus: this.props.mxEvent.getAssociatedStatus() }); this.setState({ sendStatus: this.props.mxEvent.getAssociatedStatus() });
}; };
_onRedactClick = async () => { private onRedactClick = async (): Promise<void> => {
const event = this.props.mxEvent; const event = this.props.mxEvent;
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const ConfirmAndWaitRedactDialog = sdk.getComponent("dialogs.ConfirmAndWaitRedactDialog");
Modal.createTrackedDialog('Confirm Redact Dialog', 'Edit history', ConfirmAndWaitRedactDialog, { Modal.createTrackedDialog('Confirm Redact Dialog', 'Edit history', ConfirmAndWaitRedactDialog, {
redact: () => cli.redactEvent(event.getRoomId(), event.getId()), redact: () => cli.redactEvent(event.getRoomId(), event.getId()),
}, 'mx_Dialog_confirmredact'); }, 'mx_Dialog_confirmredact');
}; };
_onViewSourceClick = () => { private onViewSourceClick = (): void => {
const ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createTrackedDialog('View Event Source', 'Edit history', ViewSource, { Modal.createTrackedDialog('View Event Source', 'Edit history', ViewSource, {
mxEvent: this.props.mxEvent, mxEvent: this.props.mxEvent,
}, 'mx_Dialog_viewsource'); }, 'mx_Dialog_viewsource');
}; };
pillifyLinks() { private pillifyLinks(): void {
// not present for redacted events // not present for redacted events
if (this._content.current) { if (this.content.current) {
pillifyLinks(this._content.current.children, this.props.mxEvent, this._pills); pillifyLinks(this.content.current.children, this.props.mxEvent, this.pills);
} }
} }
componentDidMount() { public componentDidMount(): void {
this.pillifyLinks(); this.pillifyLinks();
} }
componentWillUnmount() { public componentWillUnmount(): void {
unmountPills(this._pills); unmountPills(this.pills);
const event = this.props.mxEvent; const event = this.props.mxEvent;
if (event.localRedactionEvent()) { if (event.localRedactionEvent()) {
event.localRedactionEvent().off("status", this._onAssociatedStatusChanged); event.localRedactionEvent().off("status", this.onAssociatedStatusChanged);
} }
} }
componentDidUpdate() { public componentDidUpdate(): void {
this.pillifyLinks(); this.pillifyLinks();
} }
_renderActionBar() { private renderActionBar(): JSX.Element {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
// hide the button when already redacted // hide the button when already redacted
let redactButton; let redactButton;
if (!this.props.mxEvent.isRedacted() && !this.props.isBaseEvent && this.state.canRedact) { if (!this.props.mxEvent.isRedacted() && !this.props.isBaseEvent && this.state.canRedact) {
redactButton = ( redactButton = (
<AccessibleButton onClick={this._onRedactClick}> <AccessibleButton onClick={this.onRedactClick}>
{ _t("Remove") } { _t("Remove") }
</AccessibleButton> </AccessibleButton>
); );
} }
const viewSourceButton = ( const viewSourceButton = (
<AccessibleButton onClick={this._onViewSourceClick}> <AccessibleButton onClick={this.onViewSourceClick}>
{ _t("View Source") } { _t("View Source") }
</AccessibleButton> </AccessibleButton>
); );
@ -128,7 +133,7 @@ export default class EditHistoryMessage extends React.PureComponent {
); );
} }
render() { public render(): JSX.Element {
const { mxEvent } = this.props; const { mxEvent } = this.props;
const content = getReplacedContent(mxEvent); const content = getReplacedContent(mxEvent);
let contentContainer; let contentContainer;
@ -139,18 +144,22 @@ export default class EditHistoryMessage extends React.PureComponent {
if (this.props.previousEdit) { if (this.props.previousEdit) {
contentElements = editBodyDiffToHtml(getReplacedContent(this.props.previousEdit), content); contentElements = editBodyDiffToHtml(getReplacedContent(this.props.previousEdit), content);
} else { } else {
contentElements = HtmlUtils.bodyToHtml(content, null, { stripReplyFallback: true }); contentElements = HtmlUtils.bodyToHtml(
content,
null,
{ stripReplyFallback: true, returnString: false },
);
} }
if (mxEvent.getContent().msgtype === "m.emote") { if (mxEvent.getContent().msgtype === "m.emote") {
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
contentContainer = ( contentContainer = (
<div className="mx_EventTile_content" ref={this._content}>*&nbsp; <div className="mx_EventTile_content" ref={this.content}>*&nbsp;
<span className="mx_MEmoteBody_sender">{ name }</span> <span className="mx_MEmoteBody_sender">{ name }</span>
&nbsp;{ contentElements } &nbsp;{ contentElements }
</div> </div>
); );
} else { } else {
contentContainer = <div className="mx_EventTile_content" ref={this._content}>{ contentElements }</div>; contentContainer = <div className="mx_EventTile_content" ref={this.content}>{ contentElements }</div>;
} }
} }
@ -167,7 +176,7 @@ export default class EditHistoryMessage extends React.PureComponent {
<div className="mx_EventTile_line"> <div className="mx_EventTile_line">
<span className="mx_MessageTimestamp">{ timestamp }</span> <span className="mx_MessageTimestamp">{ timestamp }</span>
{ contentContainer } { contentContainer }
{ this._renderActionBar() } { this.renderActionBar() }
</div> </div>
</div> </div>
</li> </li>

View File

@ -21,8 +21,13 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { formatFullDate } from "../../../DateUtils"; import { formatFullDate } from "../../../DateUtils";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { IBodyProps } from "./IBodyProps"; import { IBodyProps } from "./IBodyProps";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
const RedactedBody = React.forwardRef<any, IBodyProps>(({ mxEvent }, ref) => { interface IProps {
mxEvent: MatrixEvent;
}
const RedactedBody = React.forwardRef<any, IProps | IBodyProps>(({ mxEvent }, ref) => {
const cli: MatrixClient = useContext(MatrixClientContext); const cli: MatrixClient = useContext(MatrixClientContext);
let text = _t("Message deleted"); let text = _t("Message deleted");