Merge pull request #144 from matrix-org/thumbnails
Use thumbnails api instead of mxc download
This commit is contained in:
commit
32c6119243
@ -16,13 +16,16 @@ limitations under the License.
|
|||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Group, Room, User } from '../matrix-cypher';
|
|
||||||
|
|
||||||
import { getMediaQueryFromMCX } from '../utils/cypher-wrapper';
|
import { Group, Room, User } from '../matrix-cypher';
|
||||||
|
import useHSs from '../utils/getHS';
|
||||||
|
import { getThumbnailURI } from '../utils/cypher-wrapper';
|
||||||
import logo from '../imgs/chat-icon.svg';
|
import logo from '../imgs/chat-icon.svg';
|
||||||
|
|
||||||
import './Avatar.scss';
|
import './Avatar.scss';
|
||||||
|
|
||||||
|
const AVATAR_SIZE = 96;
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
avatarUrl: string;
|
avatarUrl: string;
|
||||||
@ -56,12 +59,20 @@ interface IPropsUserAvatar {
|
|||||||
export const UserAvatar: React.FC<IPropsUserAvatar> = ({
|
export const UserAvatar: React.FC<IPropsUserAvatar> = ({
|
||||||
user,
|
user,
|
||||||
userId,
|
userId,
|
||||||
}: IPropsUserAvatar) => (
|
}: IPropsUserAvatar) => {
|
||||||
|
const [hs] = useHSs({ identifier: userId });
|
||||||
|
return (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={getMediaQueryFromMCX(user.avatar_url)}
|
avatarUrl={getThumbnailURI(
|
||||||
|
hs,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
user.avatar_url
|
||||||
|
)}
|
||||||
label={user.displayname ? user.displayname : userId}
|
label={user.displayname ? user.displayname : userId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
interface IPropsRoomAvatar {
|
interface IPropsRoomAvatar {
|
||||||
room: Room;
|
room: Room;
|
||||||
@ -69,24 +80,42 @@ interface IPropsRoomAvatar {
|
|||||||
|
|
||||||
export const RoomAvatar: React.FC<IPropsRoomAvatar> = ({
|
export const RoomAvatar: React.FC<IPropsRoomAvatar> = ({
|
||||||
room,
|
room,
|
||||||
}: IPropsRoomAvatar) => (
|
}: IPropsRoomAvatar) => {
|
||||||
|
const [hs] = useHSs({ identifier: room.room_id });
|
||||||
|
return (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={getMediaQueryFromMCX(room.avatar_url)}
|
avatarUrl={getThumbnailURI(
|
||||||
|
hs,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
room.avatar_url
|
||||||
|
)}
|
||||||
label={room.name || room.room_id}
|
label={room.name || room.room_id}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
interface IPropsGroupAvatar {
|
interface IPropsGroupAvatar {
|
||||||
group: Group;
|
group: Group;
|
||||||
|
groupId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GroupAvatar: React.FC<IPropsGroupAvatar> = ({
|
export const GroupAvatar: React.FC<IPropsGroupAvatar> = ({
|
||||||
group,
|
group,
|
||||||
}: IPropsGroupAvatar) => (
|
groupId,
|
||||||
|
}: IPropsGroupAvatar) => {
|
||||||
|
const [hs] = useHSs({ identifier: groupId });
|
||||||
|
return (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={getMediaQueryFromMCX(group.avatar_url)}
|
avatarUrl={getThumbnailURI(
|
||||||
|
hs,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
AVATAR_SIZE,
|
||||||
|
group.avatar_url
|
||||||
|
)}
|
||||||
label={group.name}
|
label={group.name}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Avatar;
|
export default Avatar;
|
||||||
|
@ -23,9 +23,10 @@ import './GroupPreview.scss';
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
group: Group;
|
group: Group;
|
||||||
|
groupId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GroupPreview: React.FC<IProps> = ({ group }: IProps) => {
|
const GroupPreview: React.FC<IProps> = ({ group, groupId }: IProps) => {
|
||||||
const description = group.long_description
|
const description = group.long_description
|
||||||
? group.long_description
|
? group.long_description
|
||||||
: group.short_description
|
: group.short_description
|
||||||
@ -34,7 +35,7 @@ const GroupPreview: React.FC<IProps> = ({ group }: IProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="groupPreview">
|
<div className="groupPreview">
|
||||||
<GroupAvatar group={group} />
|
<GroupAvatar group={group} groupId={groupId}/>
|
||||||
<h1>{group.name}</h1>
|
<h1>{group.name}</h1>
|
||||||
{description ? <p>{description}</p> : null}
|
{description ? <p>{description}</p> : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,6 +92,7 @@ const invite = async ({
|
|||||||
return (
|
return (
|
||||||
<GroupPreview
|
<GroupPreview
|
||||||
group={await getGroup(clientAddress, link.identifier)}
|
group={await getGroup(clientAddress, link.identifier)}
|
||||||
|
groupId={link.identifier}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ const LinkPreview: React.FC<IProps> = ({ link }: IProps) => {
|
|||||||
let content: JSX.Element;
|
let content: JSX.Element;
|
||||||
const [showHSOptions, setShowHSOPtions] = useState(false);
|
const [showHSOptions, setShowHSOPtions] = useState(false);
|
||||||
|
|
||||||
const hses = useHSs(link);
|
const hses = useHSs({link});
|
||||||
|
|
||||||
if (!hses.length) {
|
if (!hses.length) {
|
||||||
content = (
|
content = (
|
||||||
|
@ -84,7 +84,7 @@ export const WrappedInviterPreview: React.FC<WrappedInviterProps> = ({
|
|||||||
link,
|
link,
|
||||||
}: WrappedInviterProps) => {
|
}: WrappedInviterProps) => {
|
||||||
const [user, setUser] = useState<User | undefined>(undefined);
|
const [user, setUser] = useState<User | undefined>(undefined);
|
||||||
const hss = useHSs(link);
|
const hss = useHSs({link});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hss.length) {
|
if (hss.length) {
|
||||||
client(hss[0])
|
client(hss[0])
|
||||||
|
@ -182,6 +182,21 @@ export async function getGroupDetails(
|
|||||||
.then(GroupSchema.parse);
|
.then(GroupSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getThumbnailURI(
|
||||||
|
clientURL: string,
|
||||||
|
mxcId: string,
|
||||||
|
height: number,
|
||||||
|
width: number,
|
||||||
|
): string {
|
||||||
|
const mxcParse = mxcId.match(/mxc:\/\/(?<server>.+)\/(?<mediaId>.+)/);
|
||||||
|
if (!mxcParse || !mxcParse.groups) {
|
||||||
|
throw new Error(`mxc invalid. mxc: ${mxcId}`);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
return `https://${clientURL}/_matrix/media/r0/thumbnail/${mxcParse.groups.server}/${mxcParse.groups.mediaId}?height=${height}&width=${width}&method=crop`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets an mxc resource
|
* Gets an mxc resource
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
getUserDetails,
|
getUserDetails,
|
||||||
convertMXCtoMediaQuery,
|
convertMXCtoMediaQuery,
|
||||||
getGroupDetails,
|
getGroupDetails,
|
||||||
|
getThumbnailURI as cypherGetThumbnailURI,
|
||||||
} from '../matrix-cypher';
|
} from '../matrix-cypher';
|
||||||
import { LinkKind, Permalink } from '../parser/types';
|
import { LinkKind, Permalink } from '../parser/types';
|
||||||
|
|
||||||
@ -177,6 +178,24 @@ export function getMediaQueryFromMCX(mxc?: string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getThumbnailURI(
|
||||||
|
clientURL: string,
|
||||||
|
height: number,
|
||||||
|
width: number,
|
||||||
|
mxcId?: string,
|
||||||
|
): string {
|
||||||
|
if (!mxcId) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return cypherGetThumbnailURI(clientURL, mxcId, height, width);
|
||||||
|
} catch (e){
|
||||||
|
console.error(e);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getGroup(
|
export async function getGroup(
|
||||||
clientURL: string,
|
clientURL: string,
|
||||||
groupId: string
|
groupId: string
|
||||||
|
@ -22,7 +22,34 @@ import HSContext, {
|
|||||||
} from '../contexts/HSContext';
|
} from '../contexts/HSContext';
|
||||||
import { SafeLink } from '../parser/types';
|
import { SafeLink } from '../parser/types';
|
||||||
|
|
||||||
function selectedClient(link: SafeLink, hsOptions: State): string[] {
|
function selectedClient({ link, identifier, hsOptions }: {
|
||||||
|
link?: SafeLink,
|
||||||
|
identifier?: string;
|
||||||
|
hsOptions: State
|
||||||
|
}): string[] {
|
||||||
|
const linkHSs = link ? [
|
||||||
|
...link.identifier
|
||||||
|
.split('/')
|
||||||
|
.map((i) => 'https://' + i.split(':')[1]),
|
||||||
|
...link.arguments.vias,
|
||||||
|
] : [];
|
||||||
|
const identifierHS: string[] = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (identifier) {
|
||||||
|
const match = identifier.match(/^.*:(?<server>.*)$/);
|
||||||
|
if (match && match.groups) {
|
||||||
|
const server = match.groups.server;
|
||||||
|
if (server) {
|
||||||
|
identifierHS.push(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Could parse user identifier: ${identifier}`);
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
switch (hsOptions.option) {
|
switch (hsOptions.option) {
|
||||||
case HSOptions.Unset:
|
case HSOptions.Unset:
|
||||||
return [];
|
return [];
|
||||||
@ -30,22 +57,31 @@ function selectedClient(link: SafeLink, hsOptions: State): string[] {
|
|||||||
return [hsOptions.hs];
|
return [hsOptions.hs];
|
||||||
case HSOptions.Any:
|
case HSOptions.Any:
|
||||||
return [
|
return [
|
||||||
...link.identifier
|
...linkHSs,
|
||||||
.split('/')
|
...identifierHS,
|
||||||
.map((i) => 'https://' + i.split(':')[1]),
|
|
||||||
...link.arguments.vias,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useHSs(link: SafeLink): string[] {
|
export default function useHSs({ link, identifier }: {
|
||||||
|
link?: SafeLink,
|
||||||
|
identifier?: string,
|
||||||
|
}): string[] {
|
||||||
const [HSState] = useContext(HSContext);
|
const [HSState] = useContext(HSContext);
|
||||||
const [TempHSState] = useContext(TempHSContext);
|
const [TempHSState] = useContext(TempHSContext);
|
||||||
|
|
||||||
if (HSState.option !== HSOptions.Unset) {
|
if (HSState.option !== HSOptions.Unset) {
|
||||||
return selectedClient(link, HSState);
|
return selectedClient({
|
||||||
|
link,
|
||||||
|
identifier,
|
||||||
|
hsOptions: HSState
|
||||||
|
});
|
||||||
} else if (TempHSState.option !== HSOptions.Unset) {
|
} else if (TempHSState.option !== HSOptions.Unset) {
|
||||||
return selectedClient(link, TempHSState);
|
return selectedClient({
|
||||||
|
link,
|
||||||
|
identifier,
|
||||||
|
hsOptions: TempHSState
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user