diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 9dc9f8d484..b4a2e46feb 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -443,16 +443,18 @@ export default class EventTile extends React.Component { componentDidMount() { this.suppressReadReceiptAnimation = false; const client = this.context; - client.on("deviceVerificationChanged", this.onDeviceVerificationChanged); - client.on("userTrustStatusChanged", this.onUserVerificationChanged); - this.props.mxEvent.on("Event.decrypted", this.onDecrypted); - if (this.props.showReactions) { - this.props.mxEvent.on("Event.relationsCreated", this.onReactionsCreated); - } + if (!this.props.forExport) { + client.on("deviceVerificationChanged", this.onDeviceVerificationChanged); + client.on("userTrustStatusChanged", this.onUserVerificationChanged); + this.props.mxEvent.on("Event.decrypted", this.onDecrypted); + if (this.props.showReactions) { + this.props.mxEvent.on("Event.relationsCreated", this.onReactionsCreated); + } - if (this.shouldShowSentReceipt || this.shouldShowSendingReceipt) { - client.on("Room.receipt", this.onRoomReceipt); - this.isListeningForReceipts = true; + if (this.shouldShowSentReceipt || this.shouldShowSendingReceipt) { + client.on("Room.receipt", this.onRoomReceipt); + this.isListeningForReceipts = true; + } } } diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index 39fa762596..124b390293 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -15,17 +15,18 @@ limitations under the License. */ import React from "react"; +import ReactDOM from "react-dom"; import Exporter from "./Exporter"; import { mediaFromMxc } from "../../customisations/Media"; import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; -import { renderToStaticMarkup } from "react-dom/server"; +import { renderToStaticMarkup, renderToString } from "react-dom/server"; import { Layout } from "../../settings/Layout"; import { shouldFormContinuation } from "../../components/structures/MessagePanel"; import { formatFullDateNoDayNoTime, wantsDateSeparator } from "../../DateUtils"; import { RoomPermalinkCreator } from "../permalinks/Permalinks"; import { _t } from "../../languageHandler"; -import { EventType } from "matrix-js-sdk/src/@types/event"; +import { EventType, MsgType } from "matrix-js-sdk/src/@types/event"; import * as Avatar from "../../Avatar"; import EventTile, { haveTileForEvent } from "../../components/views/rooms/EventTile"; import DateSeparator from "../../components/views/messages/DateSeparator"; @@ -115,7 +116,7 @@ export default class HTMLExporter extends Exporter { { exporterName ? ( <> { exporterName } - { exporter } + { " (" + exporter + ")" } ) : ( { exporter } @@ -263,6 +264,7 @@ export default class HTMLExporter extends Exporter { replacingEventId={mxEv.replacingEventId()} forExport={true} readReceipts={null} + alwaysShowTimestamps={true} readReceiptMap={null} showUrlPreview={false} checkUnmounting={() => false} @@ -285,10 +287,26 @@ export default class HTMLExporter extends Exporter { protected async getEventTileMarkup(mxEv: MatrixEvent, continuation: boolean, filePath?: string) { const hasAvatar = !!this.getAvatarURL(mxEv); if (hasAvatar) await this.saveAvatarIfNeeded(mxEv); + const EventTile = this.getEventTile(mxEv, continuation); + let eventTileMarkup: string; - const eventTile = this.getEventTile(mxEv, continuation); + if ( + mxEv.getContent().msgtype == MsgType.Emote || + mxEv.getContent().msgtype == MsgType.Notice || + mxEv.getContent().msgtype === MsgType.Text + ) { + // to linkify textual events, we'll need lifecycle methods which won't be invoked in renderToString + // So, we'll have to render the component into a temporary root element + const tempRoot = document.createElement('div'); + ReactDOM.render( + EventTile, + tempRoot, + ); + eventTileMarkup = tempRoot.innerHTML; + } else { + eventTileMarkup = renderToString(EventTile); + } - let eventTileMarkup = renderToStaticMarkup(eventTile); if (filePath) { const mxc = mxEv.getContent().url || mxEv.getContent().file?.url; eventTileMarkup = eventTileMarkup.split(mxc).join(filePath); @@ -390,8 +408,7 @@ export default class HTMLExporter extends Exporter { } public async export() { - this.updateProgress("Starting export process", true, false); - this.updateProgress("Fetching events"); + this.updateProgress("Starting export..."); const fetchStart = performance.now(); const res = await this.getRequiredEvents(); diff --git a/src/utils/exportUtils/exportCSS.ts b/src/utils/exportUtils/exportCSS.ts index 965c7d775a..7f83711fc2 100644 --- a/src/utils/exportUtils/exportCSS.ts +++ b/src/utils/exportUtils/exportCSS.ts @@ -121,7 +121,7 @@ const getExportCSS = async (): Promise => { } .mx_ReplyThread_Export { - margin-top: -5px; + margin-top: 0px; margin-bottom: 5px; }