Fix "[object Promise]" appearing in HTML exports (#9975)
Fixes https://github.com/vector-im/element-web/issues/24272
This commit is contained in:
parent
3e2bf5640e
commit
4c1e4f5127
13 changed files with 895 additions and 84 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2021, 2023 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.
|
||||
|
@ -66,7 +66,7 @@ export default class HTMLExporter extends Exporter {
|
|||
}
|
||||
|
||||
protected async getRoomAvatar(): Promise<ReactNode> {
|
||||
let blob: Blob;
|
||||
let blob: Blob | undefined = undefined;
|
||||
const avatarUrl = Avatar.avatarUrlForRoom(this.room, 32, 32, "crop");
|
||||
const avatarPath = "room.png";
|
||||
if (avatarUrl) {
|
||||
|
@ -85,7 +85,7 @@ export default class HTMLExporter extends Exporter {
|
|||
height={32}
|
||||
name={this.room.name}
|
||||
title={this.room.name}
|
||||
url={blob ? avatarPath : null}
|
||||
url={blob ? avatarPath : ""}
|
||||
resizeMethod="crop"
|
||||
/>
|
||||
);
|
||||
|
@ -96,9 +96,9 @@ export default class HTMLExporter extends Exporter {
|
|||
const roomAvatar = await this.getRoomAvatar();
|
||||
const exportDate = formatFullDateNoDayNoTime(new Date());
|
||||
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
|
||||
const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator;
|
||||
const exporter = this.client.getUserId();
|
||||
const exporterName = this.room?.getMember(exporter)?.rawDisplayName;
|
||||
const creatorName = (creator ? this.room.getMember(creator)?.rawDisplayName : creator) || creator;
|
||||
const exporter = this.client.getUserId()!;
|
||||
const exporterName = this.room.getMember(exporter)?.rawDisplayName;
|
||||
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
|
||||
const createdText = _t("%(creatorName)s created this room.", {
|
||||
creatorName,
|
||||
|
@ -217,20 +217,19 @@ export default class HTMLExporter extends Exporter {
|
|||
</html>`;
|
||||
}
|
||||
|
||||
protected getAvatarURL(event: MatrixEvent): string {
|
||||
protected getAvatarURL(event: MatrixEvent): string | undefined {
|
||||
const member = event.sender;
|
||||
return (
|
||||
member.getMxcAvatarUrl() && mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(30, 30, "crop")
|
||||
);
|
||||
const avatarUrl = member?.getMxcAvatarUrl();
|
||||
return avatarUrl ? mediaFromMxc(avatarUrl).getThumbnailOfSourceHttp(30, 30, "crop") : undefined;
|
||||
}
|
||||
|
||||
protected async saveAvatarIfNeeded(event: MatrixEvent): Promise<void> {
|
||||
const member = event.sender;
|
||||
const member = event.sender!;
|
||||
if (!this.avatars.has(member.userId)) {
|
||||
try {
|
||||
const avatarUrl = this.getAvatarURL(event);
|
||||
this.avatars.set(member.userId, true);
|
||||
const image = await fetch(avatarUrl);
|
||||
const image = await fetch(avatarUrl!);
|
||||
const blob = await image.blob();
|
||||
this.addFile(`users/${member.userId.replace(/:/g, "-")}.png`, blob);
|
||||
} catch (err) {
|
||||
|
@ -239,19 +238,19 @@ export default class HTMLExporter extends Exporter {
|
|||
}
|
||||
}
|
||||
|
||||
protected async getDateSeparator(event: MatrixEvent): Promise<string> {
|
||||
protected getDateSeparator(event: MatrixEvent): string {
|
||||
const ts = event.getTs();
|
||||
const dateSeparator = (
|
||||
<li key={ts}>
|
||||
<DateSeparator forExport={true} key={ts} roomId={event.getRoomId()} ts={ts} />
|
||||
<DateSeparator forExport={true} key={ts} roomId={event.getRoomId()!} ts={ts} />
|
||||
</li>
|
||||
);
|
||||
return renderToStaticMarkup(dateSeparator);
|
||||
}
|
||||
|
||||
protected async needsDateSeparator(event: MatrixEvent, prevEvent: MatrixEvent): Promise<boolean> {
|
||||
if (prevEvent == null) return true;
|
||||
return wantsDateSeparator(prevEvent.getDate(), event.getDate());
|
||||
protected needsDateSeparator(event: MatrixEvent, prevEvent: MatrixEvent | null): boolean {
|
||||
if (!prevEvent) return true;
|
||||
return wantsDateSeparator(prevEvent.getDate() || undefined, event.getDate() || undefined);
|
||||
}
|
||||
|
||||
public getEventTile(mxEv: MatrixEvent, continuation: boolean): JSX.Element {
|
||||
|
@ -264,9 +263,7 @@ export default class HTMLExporter extends Exporter {
|
|||
isRedacted={mxEv.isRedacted()}
|
||||
replacingEventId={mxEv.replacingEventId()}
|
||||
forExport={true}
|
||||
readReceipts={null}
|
||||
alwaysShowTimestamps={true}
|
||||
readReceiptMap={null}
|
||||
showUrlPreview={false}
|
||||
checkUnmounting={() => false}
|
||||
isTwelveHour={false}
|
||||
|
@ -275,7 +272,6 @@ export default class HTMLExporter extends Exporter {
|
|||
permalinkCreator={this.permalinkCreator}
|
||||
lastSuccessful={false}
|
||||
isSelectedEvent={false}
|
||||
getRelationsForEvent={null}
|
||||
showReactions={false}
|
||||
layout={Layout.Group}
|
||||
showReadReceipts={false}
|
||||
|
@ -286,7 +282,8 @@ export default class HTMLExporter extends Exporter {
|
|||
}
|
||||
|
||||
protected async getEventTileMarkup(mxEv: MatrixEvent, continuation: boolean, filePath?: string): Promise<string> {
|
||||
const hasAvatar = !!this.getAvatarURL(mxEv);
|
||||
const avatarUrl = this.getAvatarURL(mxEv);
|
||||
const hasAvatar = !!avatarUrl;
|
||||
if (hasAvatar) await this.saveAvatarIfNeeded(mxEv);
|
||||
const EventTile = this.getEventTile(mxEv, continuation);
|
||||
let eventTileMarkup: string;
|
||||
|
@ -312,8 +309,8 @@ export default class HTMLExporter extends Exporter {
|
|||
eventTileMarkup = eventTileMarkup.replace(/<span class="mx_MFileBody_info_icon".*?>.*?<\/span>/, "");
|
||||
if (hasAvatar) {
|
||||
eventTileMarkup = eventTileMarkup.replace(
|
||||
encodeURI(this.getAvatarURL(mxEv)).replace(/&/g, "&"),
|
||||
`users/${mxEv.sender.userId.replace(/:/g, "-")}.png`,
|
||||
encodeURI(avatarUrl).replace(/&/g, "&"),
|
||||
`users/${mxEv.sender!.userId.replace(/:/g, "-")}.png`,
|
||||
);
|
||||
}
|
||||
return eventTileMarkup;
|
||||
|
|
|
@ -58,8 +58,8 @@ const getExportCSS = async (usedClasses: Set<string>): Promise<string> => {
|
|||
|
||||
// If the light theme isn't loaded we will have to fetch & parse it manually
|
||||
if (!stylesheets.some(isLightTheme)) {
|
||||
const href = document.querySelector<HTMLLinkElement>('link[rel="stylesheet"][href$="theme-light.css"]').href;
|
||||
stylesheets.push(await getRulesFromCssFile(href));
|
||||
const href = document.querySelector<HTMLLinkElement>('link[rel="stylesheet"][href$="theme-light.css"]')?.href;
|
||||
if (href) stylesheets.push(await getRulesFromCssFile(href));
|
||||
}
|
||||
|
||||
let css = "";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue