diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 3205ca372c..8550f13e2d 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -36,6 +36,7 @@ interface IProps extends Omit, "name" | // Whether the onClick of the avatar should be overriden to dispatch `Action.ViewUser` viewUserOnClick?: boolean; title?: string; + avatarSrc?: string; } interface IState { @@ -66,7 +67,8 @@ export default class MemberAvatar extends React.Component { private static getState(props: IProps): IState { if (props.member?.name) { let imageUrl = null; - if (props.member.getMxcAvatarUrl()) { + if (props.avatarSrc) imageUrl = props.avatarSrc; + else if (props.member.getMxcAvatarUrl()) { imageUrl = mediaFromMxc(props.member.getMxcAvatarUrl()).getThumbnailOfSourceHttp( props.width, props.height, diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 31cdeed6a0..9937624a0e 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -407,7 +407,7 @@ export default class MImageBody extends React.Component {
{ /* Calculate aspect ratio, using %padding will size _container correctly */ }
- { showPlaceholder && + { !this.props.mediaSrc && showPlaceholder &&
} -
+
{ img } { gifLabel }
diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 8356119d71..1f73d46e0a 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -254,6 +254,9 @@ interface IProps { // Used while exporting to refer to the local source rather than the online one mediaSrc?: string; + // Used while exporting to refer to the local avatar rather than the online one + avatarSrc?: string; + // show twelve hour timestamps isTwelveHour?: boolean; @@ -939,8 +942,11 @@ export default class EventTile extends React.Component { } avatar = (
-
diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index f124359882..914b8867a9 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -2,7 +2,7 @@ import React from "react" import streamSaver from "streamsaver"; import JSZip from "jszip"; import { decryptFile } from "../DecryptFile"; -import { mediaFromContent } from "../../customisations/Media"; +import { mediaFromContent, mediaFromMxc } from "../../customisations/Media"; import { Room } from "matrix-js-sdk/src/models/room"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { Exporter } from "./Exporter"; @@ -133,7 +133,23 @@ export default class HTMLExporter extends Exporter { ` } - // will be used in the future + protected hasAvatar(event: MatrixEvent): boolean { + const member = event.sender; + if (member.getMxcAvatarUrl()) return true; + return false; + } + + protected async saveAvatarIfNeeded(event: MatrixEvent) { + const member = event.sender; + const avatarUrl = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(30, 30, "crop"); + if (!this.avatars.has(member.userId)) { + this.avatars.set(member.userId, true); + const image = await fetch(avatarUrl); + const blob = await image.blob(); + this.zip.file(`users/${member.userId}`, blob); + } + } + protected async getMediaBlob(event: MatrixEvent) { let blob: Blob; try { @@ -165,6 +181,9 @@ export default class HTMLExporter extends Exporter { protected getEventTile(mxEv: MatrixEvent, continuation: boolean, mediaSrc?: string) { + const hasAvatar = this.hasAvatar(mxEv); + if (hasAvatar) this.saveAvatarIfNeeded(mxEv); + return