Switch secondary React trees to the createRoot API (#28296)
* Switch secondary React trees to the createRoot API Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
2f8e98242c
commit
d06cf09bf0
13 changed files with 158 additions and 140 deletions
|
@ -7,12 +7,13 @@ Please see LICENSE files in the repository root for full details.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { Room, MatrixEvent, EventType, MsgType } from "matrix-js-sdk/src/matrix";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import escapeHtml from "escape-html";
|
||||
import { TooltipProvider } from "@vector-im/compound-web";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import Exporter from "./Exporter";
|
||||
import { mediaFromMxc } from "../../customisations/Media";
|
||||
|
@ -263,7 +264,7 @@ export default class HTMLExporter extends Exporter {
|
|||
return wantsDateSeparator(prevEvent.getDate() || undefined, event.getDate() || undefined);
|
||||
}
|
||||
|
||||
public getEventTile(mxEv: MatrixEvent, continuation: boolean): JSX.Element {
|
||||
public getEventTile(mxEv: MatrixEvent, continuation: boolean, ref?: () => void): JSX.Element {
|
||||
return (
|
||||
<div className="mx_Export_EventWrapper" id={mxEv.getId()}>
|
||||
<MatrixClientContext.Provider value={this.room.client}>
|
||||
|
@ -287,6 +288,7 @@ export default class HTMLExporter extends Exporter {
|
|||
layout={Layout.Group}
|
||||
showReadReceipts={false}
|
||||
getRelationsForEvent={this.getRelationsForEvent}
|
||||
ref={ref}
|
||||
/>
|
||||
</TooltipProvider>
|
||||
</MatrixClientContext.Provider>
|
||||
|
@ -298,7 +300,10 @@ export default class HTMLExporter extends Exporter {
|
|||
const avatarUrl = this.getAvatarURL(mxEv);
|
||||
const hasAvatar = !!avatarUrl;
|
||||
if (hasAvatar) await this.saveAvatarIfNeeded(mxEv);
|
||||
const EventTile = this.getEventTile(mxEv, continuation);
|
||||
// We have to wait for the component to be rendered before we can get the markup
|
||||
// so pass a deferred as a ref to the component.
|
||||
const deferred = defer<void>();
|
||||
const EventTile = this.getEventTile(mxEv, continuation, deferred.resolve);
|
||||
let eventTileMarkup: string;
|
||||
|
||||
if (
|
||||
|
@ -308,9 +313,12 @@ export default class HTMLExporter extends Exporter {
|
|||
) {
|
||||
// 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;
|
||||
const tempElement = document.createElement("div");
|
||||
const tempRoot = createRoot(tempElement);
|
||||
tempRoot.render(EventTile);
|
||||
await deferred.promise;
|
||||
eventTileMarkup = tempElement.innerHTML;
|
||||
tempRoot.unmount();
|
||||
} else {
|
||||
eventTileMarkup = renderToStaticMarkup(EventTile);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue