mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
* incorporating configuration panes from #1078 * standardizing player hero subcomponents & removing `owner` var from `useProfileField` 🚪 * switching box type, ambiguating overly-specific names, & massaging heights 📱 * reordering profile details sections, updating deployment environment, & conditionally wrapping the hero elements 🎬 * fixing render of color disposition selector 🕍 * self code review changes: removed some `;`s 🎋 * getting yarn typecheck && yarn lint to pass post rebase 🏇🏾 * handling "missing <div> in <button>" error with mounted check & setting HTTP return codes for OpenSea API endpoint 🕺 * `ProfileWizard` extends `Wizard`, roles display better on mobile, & pronouns use `ProfileWizardPane` 🍊 * properly encapsulating ETH address regex 🚲 * adding some tasks 🏥 * fixed skills layou * handling default values? ❔ * corrections for revision comments from @dan13ram (UI bugs to follow) 🌋 * cleaning up memberships & explorer type 🧫 * refactoring player roles configuration and display to use `WizardPane` 🔮 * bunches of mobile fixes & repairing the display of deserialized skills 📟 * removing redirect in static props & formatting memberships display for responsiveness 🪆 * improving comprehensability of `/me` & more mobile tweaking 🍦 * various spacing fixes & a “try again” button for connecting 🫕 * maybe fixed issue with saving images for fields with default values 🇩🇿 * switched roles selection to a bounded `SimpleGrid` to fix sizing weirdness 🧰 * fix: removed verify on brightId button * fix: clean up username page * formatting & fixing skills issues 🥩 * reformatting NFT display 🚂 * adding `/join` 🚉 * style: peth's suggestions * added mainnet required message * style: slight tweak of megamenu item positions * chore(release): 0.2.0 Co-authored-by: tenfinney <scott@1box.onmicrosoft.com> Co-authored-by: dan13ram <dan13ram@gmail.com> Co-authored-by: vidvidvid <weetopol@gmail.com>
131 lines
3.1 KiB
TypeScript
131 lines
3.1 KiB
TypeScript
import {
|
|
Box,
|
|
Flex,
|
|
LinkBox,
|
|
LinkOverlay,
|
|
LoadingState,
|
|
Text,
|
|
} from '@metafam/ds';
|
|
import { ProfileSection } from 'components/Profile/ProfileSection';
|
|
import { Maybe } from 'graphql/autogen/types';
|
|
import { useDelay } from 'lib/hooks/useDelay';
|
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { BoxTypes } from 'utils/boxTypes';
|
|
|
|
const metadataLink = '/api/metadata?url=';
|
|
|
|
type EmbeddedUrlProps = {
|
|
url?: string;
|
|
editing?: boolean;
|
|
};
|
|
|
|
export const EmbeddedUrl: React.FC<EmbeddedUrlProps> = ({ url, editing }) => (
|
|
<ProfileSection
|
|
{...{ editing }}
|
|
type={BoxTypes.EMBEDDED_URL}
|
|
pb={0}
|
|
withoutBG
|
|
>
|
|
<LinkPreview {...{ url, editing }} />
|
|
</ProfileSection>
|
|
);
|
|
|
|
interface LinkPreviewProps {
|
|
url?: string;
|
|
editing?: boolean;
|
|
}
|
|
|
|
interface URIMetadata {
|
|
url?: Maybe<string>;
|
|
title?: Maybe<string>;
|
|
description?: Maybe<string>;
|
|
image?: Maybe<string>;
|
|
site_name?: Maybe<string>;
|
|
}
|
|
|
|
const LinkPreview: React.FC<LinkPreviewProps> = ({ url: inputUrl = '' }) => {
|
|
const [metadata, setMetadata] = useState<Maybe<URIMetadata>>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
const updateMetadata = useCallback(async (uri: string) => {
|
|
setLoading(true);
|
|
try {
|
|
const res = await fetch(metadataLink + uri);
|
|
const { error, response } = await res.json();
|
|
|
|
if (error) throw error;
|
|
|
|
setMetadata((response.og as unknown) as URIMetadata);
|
|
} catch (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.error(`No metadata found for the URL: ${uri}.`, err);
|
|
setMetadata(null);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const delayedUpdate = useDelay(updateMetadata);
|
|
|
|
useEffect(() => delayedUpdate(inputUrl), [inputUrl, delayedUpdate]);
|
|
|
|
if (!metadata || loading) {
|
|
return (
|
|
<Box
|
|
minH="18rem"
|
|
w="100%"
|
|
h="100%"
|
|
borderRadius="lg"
|
|
backdropFilter="blur(7px)"
|
|
borderWidth={0}
|
|
>
|
|
{loading && <LoadingState />}
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
const { image, description, title, site_name: siteName, url } = metadata;
|
|
|
|
return (
|
|
<LinkBox
|
|
minH="18rem"
|
|
w="100%"
|
|
h="100%"
|
|
borderRadius="lg"
|
|
backdropFilter="blur(7px)"
|
|
borderWidth={0}
|
|
overflow="hidden"
|
|
>
|
|
<Flex w="100%" h="100%" direction="column">
|
|
<Box
|
|
bgImage={image ? `url(${image})` : 'none'}
|
|
height="auto"
|
|
h="12rem"
|
|
w="100%"
|
|
bgSize="cover"
|
|
bgRepeat="no-repeat"
|
|
bgPosition="center"
|
|
/>
|
|
<Box p={4}>
|
|
<LinkOverlay href={url ?? inputUrl} isExternal>
|
|
<Text fontSize="md" fontWeight="900" color="white">
|
|
{title}
|
|
</Text>
|
|
</LinkOverlay>
|
|
{description && (
|
|
<Box mt={1}>
|
|
<Text fontSize="sm" color="white" noOfLines={3}>
|
|
{description}
|
|
</Text>
|
|
</Box>
|
|
)}
|
|
<Box mt={1} color="cyanText" fontSize="sm">
|
|
{siteName && <Text as="span">{siteName} • </Text>}
|
|
<Text isTruncated>{url}</Text>
|
|
</Box>
|
|
</Box>
|
|
</Flex>
|
|
</LinkBox>
|
|
);
|
|
};
|