Save users' avatars

pull/21833/head
Jaiwanth 2021-05-31 22:27:29 +05:30
parent fa073cd958
commit 28a1a551fe
4 changed files with 35 additions and 7 deletions

View File

@ -36,6 +36,7 @@ interface IProps extends Omit<React.ComponentProps<typeof BaseAvatar>, "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<IProps, IState> {
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,

View File

@ -407,7 +407,7 @@ export default class MImageBody extends React.Component {
<div className="mx_MImageBody_thumbnail_container" style={{ maxHeight: maxHeight + "px" }} >
{ /* Calculate aspect ratio, using %padding will size _container correctly */ }
<div style={{ paddingBottom: (100 * infoHeight / infoWidth) + '%' }} />
{ showPlaceholder &&
{ !this.props.mediaSrc && showPlaceholder &&
<div className="mx_MImageBody_thumbnail" style={{
// Constrain width here so that spinner appears central to the loaded thumbnail
maxWidth: infoWidth + "px",
@ -418,7 +418,7 @@ export default class MImageBody extends React.Component {
</div>
}
<div style={{display: !showPlaceholder ? undefined : 'none'}}>
<div style={{display: this.props.mediaSrc ? "block" : !showPlaceholder ? undefined : 'none'}}>
{ img }
{ gifLabel }
</div>

View File

@ -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<IProps, IState> {
}
avatar = (
<div className="mx_EventTile_avatar">
<MemberAvatar member={member}
width={avatarSize} height={avatarSize}
<MemberAvatar
avatarSrc = {this.props.avatarSrc}
member={member}
width={avatarSize}
height={avatarSize}
viewUserOnClick={true}
/>
</div>

View File

@ -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 {
</html>`
}
// 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 <li id={mxEv.getId()}>
<EventTile
mxEvent={mxEv}
@ -179,6 +198,7 @@ export default class HTMLExporter extends Exporter {
isTwelveHour={false}
last={false}
mediaSrc={mediaSrc}
avatarSrc={hasAvatar ? `users/${mxEv.sender.userId}` : null}
lastInSection={false}
permalinkCreator={this.permalinkCreator}
lastSuccessful={false}