mirror of
https://github.com/vector-im/element-call.git
synced 2026-07-24 19:19:21 +00:00
Load authenicated media
This commit is contained in:
@@ -5,11 +5,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
Please see LICENSE in the repository root for full details.
|
Please see LICENSE in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useMemo, FC, CSSProperties } from "react";
|
import { useMemo, FC, CSSProperties, useState, useEffect } from "react";
|
||||||
import { Avatar as CompoundAvatar } from "@vector-im/compound-web";
|
import { Avatar as CompoundAvatar } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import { getAvatarUrl } from "./utils/matrix";
|
|
||||||
import { useClient } from "./ClientContext";
|
import { useClient } from "./ClientContext";
|
||||||
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
|
|
||||||
export enum Size {
|
export enum Size {
|
||||||
XS = "xs",
|
XS = "xs",
|
||||||
@@ -36,6 +36,18 @@ interface Props {
|
|||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAvatarUrl(
|
||||||
|
client: MatrixClient,
|
||||||
|
mxcUrl: string|null,
|
||||||
|
avatarSize = 96,
|
||||||
|
): string|null {
|
||||||
|
const width = Math.floor(avatarSize * window.devicePixelRatio);
|
||||||
|
const height = Math.floor(avatarSize * window.devicePixelRatio);
|
||||||
|
// scale is more suitable for larger sizes
|
||||||
|
const resizeMethod = avatarSize <= 96 ? "crop" : "scale";
|
||||||
|
return mxcUrl ? client.mxcUrlToHttp(mxcUrl, width, height, resizeMethod, false, true, true) : null;
|
||||||
|
}
|
||||||
|
|
||||||
export const Avatar: FC<Props> = ({
|
export const Avatar: FC<Props> = ({
|
||||||
className,
|
className,
|
||||||
id,
|
id,
|
||||||
@@ -55,9 +67,36 @@ export const Avatar: FC<Props> = ({
|
|||||||
[size],
|
[size],
|
||||||
);
|
);
|
||||||
|
|
||||||
const resolvedSrc = useMemo(() => {
|
const [avatarUrl, setAvatarUrl] = useState<string|undefined>(undefined);
|
||||||
if (!client || !src || !sizePx) return undefined;
|
|
||||||
return src.startsWith("mxc://") ? getAvatarUrl(client, src, sizePx) : src;
|
useEffect(() => {
|
||||||
|
if (!client || !src || !sizePx) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
const token = client.getAccessToken();
|
||||||
|
if (!token) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const resolveSrc = getAvatarUrl(client, src, sizePx);
|
||||||
|
if (!resolveSrc) {
|
||||||
|
setAvatarUrl(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let objectUrl: string|undefined;
|
||||||
|
fetch(resolveSrc, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}).then((req) => req.blob()).then((res) => {
|
||||||
|
objectUrl = URL.createObjectURL(res);
|
||||||
|
setAvatarUrl(objectUrl);
|
||||||
|
}).catch((ex) => {
|
||||||
|
console.warn("Failed to get avatar URL", ex);
|
||||||
|
setAvatarUrl(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
() => objectUrl && URL.revokeObjectURL(objectUrl);
|
||||||
}, [client, src, sizePx]);
|
}, [client, src, sizePx]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -66,7 +105,7 @@ export const Avatar: FC<Props> = ({
|
|||||||
id={id}
|
id={id}
|
||||||
name={name}
|
name={name}
|
||||||
size={`${sizePx}px`}
|
size={`${sizePx}px`}
|
||||||
src={resolvedSrc}
|
src={avatarUrl}
|
||||||
style={style}
|
style={style}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -332,16 +332,4 @@ export function getRelativeRoomUrl(
|
|||||||
? "/" + roomAliasLocalpartFromRoomName(roomName)
|
? "/" + roomAliasLocalpartFromRoomName(roomName)
|
||||||
: "";
|
: "";
|
||||||
return `/room/#${roomPart}?${generateUrlSearchParams(roomId, encryptionSystem, viaServers).toString()}`;
|
return `/room/#${roomPart}?${generateUrlSearchParams(roomId, encryptionSystem, viaServers).toString()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAvatarUrl(
|
|
||||||
client: MatrixClient,
|
|
||||||
mxcUrl: string,
|
|
||||||
avatarSize = 96,
|
|
||||||
): string {
|
|
||||||
const width = Math.floor(avatarSize * window.devicePixelRatio);
|
|
||||||
const height = Math.floor(avatarSize * window.devicePixelRatio);
|
|
||||||
// scale is more suitable for larger sizes
|
|
||||||
const resizeMethod = avatarSize <= 96 ? "crop" : "scale";
|
|
||||||
return mxcUrl && client.mxcUrlToHttp(mxcUrl, width, height, resizeMethod)!;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user