You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-11-04 11:51:45 +03:00 
			
		
		
		
	Convert EditHistoryMessage to TS
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
		
							
								
								
									
										185
									
								
								src/components/views/messages/EditHistoryMessage.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/components/views/messages/EditHistoryMessage.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2019 The Matrix.org Foundation C.I.C.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import React, { createRef } from 'react';
 | 
			
		||||
import * as HtmlUtils from '../../../HtmlUtils';
 | 
			
		||||
import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils';
 | 
			
		||||
import { formatTime } from '../../../DateUtils';
 | 
			
		||||
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
 | 
			
		||||
import { pillifyLinks, unmountPills } from '../../../utils/pillify';
 | 
			
		||||
import { _t } from '../../../languageHandler';
 | 
			
		||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
 | 
			
		||||
import Modal from '../../../Modal';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import RedactedBody from "./RedactedBody";
 | 
			
		||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
 | 
			
		||||
import AccessibleButton from "../elements/AccessibleButton";
 | 
			
		||||
import ConfirmAndWaitRedactDialog from "../dialogs/ConfirmAndWaitRedactDialog";
 | 
			
		||||
import ViewSource from "../../structures/ViewSource";
 | 
			
		||||
 | 
			
		||||
function getReplacedContent(event) {
 | 
			
		||||
    const originalContent = event.getOriginalContent();
 | 
			
		||||
    return originalContent["m.new_content"] || originalContent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IProps {
 | 
			
		||||
    // the message event being edited
 | 
			
		||||
    mxEvent: MatrixEvent;
 | 
			
		||||
    previousEdit?: MatrixEvent;
 | 
			
		||||
    isBaseEvent?: boolean;
 | 
			
		||||
    isTwelveHour?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
        const cli = MatrixClientPeg.get();
 | 
			
		||||
        const { userId } = cli.credentials;
 | 
			
		||||
        const event = this.props.mxEvent;
 | 
			
		||||
        const room = cli.getRoom(event.getRoomId());
 | 
			
		||||
        if (event.localRedactionEvent()) {
 | 
			
		||||
            event.localRedactionEvent().on("status", this.onAssociatedStatusChanged);
 | 
			
		||||
        }
 | 
			
		||||
        const canRedact = room.currentState.maySendRedactionForEvent(event, userId);
 | 
			
		||||
        this.state = { canRedact, sendStatus: event.getAssociatedStatus() };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private onAssociatedStatusChanged = (): void => {
 | 
			
		||||
        this.setState({ sendStatus: this.props.mxEvent.getAssociatedStatus() });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private onRedactClick = async (): Promise<void> => {
 | 
			
		||||
        const event = this.props.mxEvent;
 | 
			
		||||
        const cli = MatrixClientPeg.get();
 | 
			
		||||
 | 
			
		||||
        Modal.createTrackedDialog('Confirm Redact Dialog', 'Edit history', ConfirmAndWaitRedactDialog, {
 | 
			
		||||
            redact: () => cli.redactEvent(event.getRoomId(), event.getId()),
 | 
			
		||||
        }, 'mx_Dialog_confirmredact');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private onViewSourceClick = (): void => {
 | 
			
		||||
        Modal.createTrackedDialog('View Event Source', 'Edit history', ViewSource, {
 | 
			
		||||
            mxEvent: this.props.mxEvent,
 | 
			
		||||
        }, 'mx_Dialog_viewsource');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private pillifyLinks(): void {
 | 
			
		||||
        // not present for redacted events
 | 
			
		||||
        if (this.content.current) {
 | 
			
		||||
            pillifyLinks(this.content.current.children, this.props.mxEvent, this.pills);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public componentDidMount(): void {
 | 
			
		||||
        this.pillifyLinks();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public componentWillUnmount(): void {
 | 
			
		||||
        unmountPills(this.pills);
 | 
			
		||||
        const event = this.props.mxEvent;
 | 
			
		||||
        if (event.localRedactionEvent()) {
 | 
			
		||||
            event.localRedactionEvent().off("status", this.onAssociatedStatusChanged);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public componentDidUpdate(): void {
 | 
			
		||||
        this.pillifyLinks();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private renderActionBar(): JSX.Element {
 | 
			
		||||
        // hide the button when already redacted
 | 
			
		||||
        let redactButton;
 | 
			
		||||
        if (!this.props.mxEvent.isRedacted() && !this.props.isBaseEvent && this.state.canRedact) {
 | 
			
		||||
            redactButton = (
 | 
			
		||||
                <AccessibleButton onClick={this.onRedactClick}>
 | 
			
		||||
                    { _t("Remove") }
 | 
			
		||||
                </AccessibleButton>
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        const viewSourceButton = (
 | 
			
		||||
            <AccessibleButton onClick={this.onViewSourceClick}>
 | 
			
		||||
                { _t("View Source") }
 | 
			
		||||
            </AccessibleButton>
 | 
			
		||||
        );
 | 
			
		||||
        // disabled remove button when not allowed
 | 
			
		||||
        return (
 | 
			
		||||
            <div className="mx_MessageActionBar">
 | 
			
		||||
                { redactButton }
 | 
			
		||||
                { viewSourceButton }
 | 
			
		||||
            </div>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public render(): JSX.Element {
 | 
			
		||||
        const { mxEvent } = this.props;
 | 
			
		||||
        const content = getReplacedContent(mxEvent);
 | 
			
		||||
        let contentContainer;
 | 
			
		||||
        if (mxEvent.isRedacted()) {
 | 
			
		||||
            contentContainer = <RedactedBody mxEvent={this.props.mxEvent} />;
 | 
			
		||||
        } else {
 | 
			
		||||
            let contentElements;
 | 
			
		||||
            if (this.props.previousEdit) {
 | 
			
		||||
                contentElements = editBodyDiffToHtml(getReplacedContent(this.props.previousEdit), content);
 | 
			
		||||
            } else {
 | 
			
		||||
                contentElements = HtmlUtils.bodyToHtml(
 | 
			
		||||
                    content,
 | 
			
		||||
                    null,
 | 
			
		||||
                    { stripReplyFallback: true, returnString: false },
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            if (mxEvent.getContent().msgtype === "m.emote") {
 | 
			
		||||
                const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
 | 
			
		||||
                contentContainer = (
 | 
			
		||||
                    <div className="mx_EventTile_content" ref={this.content}>* 
 | 
			
		||||
                        <span className="mx_MEmoteBody_sender">{ name }</span>
 | 
			
		||||
                         { contentElements }
 | 
			
		||||
                    </div>
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                contentContainer = <div className="mx_EventTile_content" ref={this.content}>{ contentElements }</div>;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const timestamp = formatTime(new Date(mxEvent.getTs()), this.props.isTwelveHour);
 | 
			
		||||
        const isSending = (['sending', 'queued', 'encrypting'].indexOf(this.state.sendStatus) !== -1);
 | 
			
		||||
        const classes = classNames({
 | 
			
		||||
            "mx_EventTile": true,
 | 
			
		||||
            // Note: we keep the `sending` state class for tests, not for our styles
 | 
			
		||||
            "mx_EventTile_sending": isSending,
 | 
			
		||||
        });
 | 
			
		||||
        return (
 | 
			
		||||
            <li>
 | 
			
		||||
                <div className={classes}>
 | 
			
		||||
                    <div className="mx_EventTile_line">
 | 
			
		||||
                        <span className="mx_MessageTimestamp">{ timestamp }</span>
 | 
			
		||||
                        { contentContainer }
 | 
			
		||||
                        { this.renderActionBar() }
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </li>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user