diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 222790c..4dcffc9 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -16,13 +16,16 @@ 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'; +const AVATAR_SIZE = 96; + interface IProps { className?: string; avatarUrl: string; @@ -56,12 +59,20 @@ interface IPropsUserAvatar { export const UserAvatar: React.FC = ({ user, userId, -}: IPropsUserAvatar) => ( - -); +}: IPropsUserAvatar) => { + const [hs] = useHSs({ identifier: userId }); + return ( + + ); +}; interface IPropsRoomAvatar { room: Room; @@ -69,24 +80,42 @@ interface IPropsRoomAvatar { export const RoomAvatar: React.FC = ({ room, -}: IPropsRoomAvatar) => ( - -); +}: IPropsRoomAvatar) => { + const [hs] = useHSs({ identifier: room.room_id }); + return ( + + ); +}; interface IPropsGroupAvatar { group: Group; + groupId: string; } export const GroupAvatar: React.FC = ({ group, -}: IPropsGroupAvatar) => ( - -); + groupId, +}: 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..7697200 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}&method=crop`; +} + + /* * 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 []; }