Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix html export not including images #9260

Merged
merged 4 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 29 additions & 21 deletions src/components/views/messages/MImageBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
// By doing this, the image "pops" into the timeline, but is still restricted
// by the same width and height logic below.
if (!this.state.loadedImageDimensions) {
let imageElement;
let imageElement: JSX.Element;
if (!this.state.showImage) {
imageElement = <HiddenImagePlaceholder />;
} else {
Expand Down Expand Up @@ -425,7 +425,13 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
let gifLabel: JSX.Element;

if (!this.props.forExport && !this.state.imgLoaded) {
placeholder = this.getPlaceholder(maxWidth, maxHeight);
const classes = classNames('mx_MImageBody_placeholder', {
'mx_MImageBody_placeholder--blurhash': this.props.mxEvent.getContent().info?.[BLURHASH_FIELD],
});

placeholder = <div className={classes}>
{ this.getPlaceholder(maxWidth, maxHeight) }
</div>;
}

let showPlaceholder = Boolean(placeholder);
Expand Down Expand Up @@ -463,29 +469,26 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
banner = this.getBanner(content);
}

const classes = classNames({
'mx_MImageBody_placeholder': true,
'mx_MImageBody_placeholder--blurhash': this.props.mxEvent.getContent().info?.[BLURHASH_FIELD],
});

// many SVGs don't have an intrinsic size if used in <img> elements.
// due to this we have to set our desired width directly.
// this way if the image is forced to shrink, the height adapts appropriately.
const sizing = infoSvg ? { maxHeight, maxWidth, width: maxWidth } : { maxHeight, maxWidth };

if (!this.props.forExport) {
placeholder = <SwitchTransition mode="out-in">
<CSSTransition
classNames="mx_rtg--fade"
key={`img-${showPlaceholder}`}
timeout={300}
>
{ showPlaceholder ? placeholder : <></> /* Transition always expects a child */ }
</CSSTransition>
</SwitchTransition>;
}

const thumbnail = (
<div className="mx_MImageBody_thumbnail_container" style={{ maxHeight, maxWidth, aspectRatio: `${infoWidth}/${infoHeight}` }}>
<SwitchTransition mode="out-in">
<CSSTransition
classNames="mx_rtg--fade"
key={`img-${showPlaceholder}`}
timeout={300}
>
{ showPlaceholder ? <div className={classes}>
{ placeholder }
</div> : <></> /* Transition always expects a child */ }
</CSSTransition>
</SwitchTransition>
{ placeholder }

<div style={sizing}>
{ img }
Expand All @@ -494,7 +497,9 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
</div>

{ /* HACK: This div fills out space while the image loads, to prevent scroll jumps */ }
{ !this.state.imgLoaded && <div style={{ height: maxHeight, width: maxWidth }} /> }
{ !this.props.forExport && !this.state.imgLoaded && (
<div style={{ height: maxHeight, width: maxWidth }} />
) }

{ this.state.hover && this.getTooltip() }
</div>
Expand Down Expand Up @@ -559,9 +564,12 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
);
}

const contentUrl = this.state.contentUrl;
let contentUrl = this.state.contentUrl;
let thumbUrl: string;
if (this.props.forExport || (this.state.isAnimated && SettingsStore.getValue("autoplayGifs"))) {
if (this.props.forExport) {
contentUrl = this.props.mxEvent.getContent().url ?? this.props.mxEvent.getContent().file?.url;
thumbUrl = contentUrl;
} else if (this.state.isAnimated && SettingsStore.getValue("autoplayGifs")) {
thumbUrl = contentUrl;
} else {
thumbUrl = this.state.thumbUrl ?? this.state.contentUrl;
Expand Down
6 changes: 4 additions & 2 deletions src/utils/exportUtils/HtmlExport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ export default class HTMLExporter extends Exporter {
}

if (filePath) {
const mxc = mxEv.getContent().url || mxEv.getContent().file?.url;
const mxc = mxEv.getContent().url ?? mxEv.getContent().file?.url;
eventTileMarkup = eventTileMarkup.split(mxc).join(filePath);
}
eventTileMarkup = eventTileMarkup.replace(/<span class="mx_MFileBody_info_icon".*?>.*?<\/span>/, '');
Expand Down Expand Up @@ -382,7 +382,9 @@ export default class HTMLExporter extends Exporter {
joined,
);
}
} else eventTile = await this.getEventTileMarkup(mxEv, joined);
} else {
eventTile = await this.getEventTileMarkup(mxEv, joined);
}
} catch (e) {
// TODO: Handle callEvent errors
logger.error(e);
Expand Down
35 changes: 35 additions & 0 deletions test/utils/export-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@ describe('export', function() {
});
}

function mkImageEvent() {
return new MatrixEvent({
"content": {
"body": "image.png",
"info": {
"mimetype": "image/png",
"size": 31613,
},
"msgtype": "m.image",
"url": "mxc://test.org",
},
"origin_server_ts": 1628872988364,
"sender": MY_USER_ID,
"type": "m.room.message",
"unsigned": {
"age": 266,
"transaction_id": "m99999999.2",
},
"event_id": "$99999999999999999999",
"room_id": mockRoom.roomId,
});
}

function mkEvents() {
const matrixEvents = [];
let i: number;
Expand Down Expand Up @@ -204,6 +227,18 @@ describe('export', function() {
).toBeTruthy();
});

it("should export images if attachments are enabled", () => {
const exporter = new HTMLExporter(mockRoom, ExportType.Beginning, {
numberOfMessages: 5,
maxSize: 100 * 1024 * 1024,
attachmentsIncluded: true,
}, null);
const imageRegex = /<img.+ src="mxc:\/\/test.org" alt="image.png"\/>/;
expect(imageRegex.test(
renderToString(exporter.getEventTile(mkImageEvent(), true))),
).toBeTruthy();
});

const invalidExportOptions: [string, IExportOptions][] = [
['numberOfMessages exceeds max', {
numberOfMessages: 10 ** 9,
Expand Down