From ee8c860507d0ceba2cb97712ad2deebc3aef7976 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Wed, 23 Sep 2020 15:30:46 +0100 Subject: [PATCH] Use thumbnails instead of mxc download --- src/components/Avatar.tsx | 40 +++++++++++++---------- src/components/GroupPreview.tsx | 5 +-- src/components/LinkPreview.tsx | 3 +- src/components/UserPreview.tsx | 2 +- src/matrix-cypher/matrix-cypher.ts | 15 +++++++++ src/utils/cypher-wrapper.ts | 19 +++++++++++ src/utils/getHS.ts | 52 +++++++++++++++++++++++++----- 7 files changed, 107 insertions(+), 29 deletions(-) diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 222790c..9783729 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -16,9 +16,10 @@ limitations under the License. import React, { useEffect, useState } from 'react'; 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 './Avatar.scss'; @@ -56,12 +57,13 @@ interface IPropsUserAvatar { export const UserAvatar: React.FC = ({ user, userId, -}: IPropsUserAvatar) => ( - { + const [hs] = useHSs({identifier: userId}); + return -); + />; +} interface IPropsRoomAvatar { room: Room; @@ -69,24 +71,28 @@ interface IPropsRoomAvatar { export const RoomAvatar: React.FC = ({ room, -}: IPropsRoomAvatar) => ( - { + const [hs] = useHSs({identifier: room.room_id}); + return -); + />; +} interface IPropsGroupAvatar { group: Group; + groupId: string; } export const GroupAvatar: React.FC = ({ group, -}: IPropsGroupAvatar) => ( - { + const [hs] = useHSs({identifier: groupId}); + return -); + />; +} export default Avatar; diff --git a/src/components/GroupPreview.tsx b/src/components/GroupPreview.tsx index f90ecf2..49a2c22 100644 --- a/src/components/GroupPreview.tsx +++ b/src/components/GroupPreview.tsx @@ -23,9 +23,10 @@ import './GroupPreview.scss'; interface IProps { group: Group; + groupId: string; } -const GroupPreview: React.FC = ({ group }: IProps) => { +const GroupPreview: React.FC = ({ group, groupId }: IProps) => { const description = group.long_description ? group.long_description : group.short_description @@ -34,7 +35,7 @@ const GroupPreview: React.FC = ({ group }: IProps) => { return (
- +

{group.name}

{description ?

{description}

: null}
diff --git a/src/components/LinkPreview.tsx b/src/components/LinkPreview.tsx index 0372221..d063f81 100644 --- a/src/components/LinkPreview.tsx +++ b/src/components/LinkPreview.tsx @@ -92,6 +92,7 @@ const invite = async ({ return ( ); @@ -126,7 +127,7 @@ const LinkPreview: React.FC = ({ link }: IProps) => { let content: JSX.Element; const [showHSOptions, setShowHSOPtions] = useState(false); - const hses = useHSs(link); + const hses = useHSs({link}); if (!hses.length) { content = ( diff --git a/src/components/UserPreview.tsx b/src/components/UserPreview.tsx index f0928c8..6122977 100644 --- a/src/components/UserPreview.tsx +++ b/src/components/UserPreview.tsx @@ -84,7 +84,7 @@ export const WrappedInviterPreview: React.FC = ({ link, }: WrappedInviterProps) => { const [user, setUser] = useState(undefined); - const hss = useHSs(link); + const hss = useHSs({link}); useEffect(() => { if (hss.length) { client(hss[0]) diff --git a/src/matrix-cypher/matrix-cypher.ts b/src/matrix-cypher/matrix-cypher.ts index c24947a..5744a4a 100644 --- a/src/matrix-cypher/matrix-cypher.ts +++ b/src/matrix-cypher/matrix-cypher.ts @@ -182,6 +182,21 @@ export async function getGroupDetails( .then(GroupSchema.parse); } +export function getThumbnailURI( + clientURL: string, + mxcId: string, + height: number, + width: number, +): string { + const mxcParse = mxcId.match(/mxc:\/\/(?.+)\/(?.+)/); + 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}`; +} + + /* * Gets an mxc resource */ diff --git a/src/utils/cypher-wrapper.ts b/src/utils/cypher-wrapper.ts index 0e30ba0..4fb939f 100644 --- a/src/utils/cypher-wrapper.ts +++ b/src/utils/cypher-wrapper.ts @@ -30,6 +30,7 @@ import { getUserDetails, convertMXCtoMediaQuery, getGroupDetails, + getThumbnailURI as cypherGetThumbnailURI, } from '../matrix-cypher'; 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( clientURL: string, groupId: string diff --git a/src/utils/getHS.ts b/src/utils/getHS.ts index b8239da..237ef4f 100644 --- a/src/utils/getHS.ts +++ b/src/utils/getHS.ts @@ -22,7 +22,34 @@ import HSContext, { } from '../contexts/HSContext'; 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(/^.*:(?.*)$/); + 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) { case HSOptions.Unset: return []; @@ -30,22 +57,31 @@ function selectedClient(link: SafeLink, hsOptions: State): string[] { return [hsOptions.hs]; case HSOptions.Any: return [ - ...link.identifier - .split('/') - .map((i) => 'https://' + i.split(':')[1]), - ...link.arguments.vias, + ...linkHSs, + ...identifierHS, ]; } } -export default function useHSs(link: SafeLink): string[] { +export default function useHSs({ link, identifier }: { + link?: SafeLink, + identifier?: string, +}): string[] { const [HSState] = useContext(HSContext); const [TempHSState] = useContext(TempHSContext); if (HSState.option !== HSOptions.Unset) { - return selectedClient(link, HSState); + return selectedClient({ + link, + identifier, + hsOptions: HSState + }); } else if (TempHSState.option !== HSOptions.Unset) { - return selectedClient(link, TempHSState); + return selectedClient({ + link, + identifier, + hsOptions: TempHSState + }); } else { return []; }