mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import { Box, chakra } from '@chakra-ui/react';
|
|
import type { SpecifyAd } from '@specify-sh/sdk';
|
|
import Specify, { ImageFormat } from '@specify-sh/sdk';
|
|
import React from 'react';
|
|
|
|
import type { BannerProps } from './types';
|
|
|
|
import useIsMobile from 'lib/hooks/useIsMobile';
|
|
import { Image } from 'toolkit/chakra/image';
|
|
|
|
import {
|
|
DESKTOP_BANNER_HEIGHT,
|
|
DESKTOP_BANNER_WIDTH,
|
|
MOBILE_BANNER_WIDTH,
|
|
MOBILE_BANNER_HEIGHT,
|
|
} from './consts';
|
|
|
|
const PUBLISHER_KEY = 'spk_uq51124ciii28vt00f8za4m5hibpuh';
|
|
|
|
type Props = BannerProps & {
|
|
address: `0x${ string }` | undefined;
|
|
onEmpty: () => void;
|
|
isLoading: boolean;
|
|
};
|
|
|
|
const SpecifyBanner = ({ className, format = 'responsive', address, onEmpty, isLoading }: Props) => {
|
|
const isMobileViewport = useIsMobile();
|
|
const isMobile = format === 'mobile' || (format === 'responsive' && isMobileViewport);
|
|
const [ ad, setAd ] = React.useState<SpecifyAd | null>(null);
|
|
const [ isFetching, setIsFetching ] = React.useState(true);
|
|
|
|
React.useEffect(() => {
|
|
if (!isLoading) {
|
|
const specify = new Specify({
|
|
publisherKey: PUBLISHER_KEY,
|
|
cacheMostRecentAddress: true,
|
|
});
|
|
const fetchContent = async() => {
|
|
try {
|
|
const content = await specify.serve(
|
|
address ? [ address as `0x${ string }` ] : null,
|
|
{ imageFormat: isMobile ? ImageFormat.SHORT_BANNER : ImageFormat.LONG_BANNER },
|
|
);
|
|
if (content?.imageUrl) {
|
|
setAd(content);
|
|
} else {
|
|
onEmpty();
|
|
}
|
|
} catch (error) {
|
|
onEmpty();
|
|
} finally {
|
|
setIsFetching(false);
|
|
}
|
|
};
|
|
|
|
fetchContent();
|
|
}
|
|
}, [ address, isMobile, onEmpty, isLoading ]);
|
|
|
|
const handleClick = React.useCallback(() => {
|
|
window.open(ad?.ctaUrl, '_blank', 'noopener,noreferrer');
|
|
}, [ ad?.ctaUrl ]);
|
|
|
|
const { width, height } = (() => {
|
|
if (isMobile) {
|
|
return { width: MOBILE_BANNER_WIDTH, height: MOBILE_BANNER_HEIGHT };
|
|
}
|
|
return { width: DESKTOP_BANNER_WIDTH, height: DESKTOP_BANNER_HEIGHT };
|
|
})();
|
|
|
|
if (isLoading || isFetching) {
|
|
return (
|
|
<Box className={ className }
|
|
h={ height ? `${ height }px` : { base: `${ MOBILE_BANNER_HEIGHT }px`, lg: `${ DESKTOP_BANNER_HEIGHT }px` } }
|
|
w={ width ? `${ width }px` : undefined }
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (!ad) return null;
|
|
|
|
return (
|
|
<Image
|
|
src={ ad.imageUrl }
|
|
alt={ ad.headline }
|
|
cursor="pointer"
|
|
onClick={ handleClick }
|
|
className={ className }
|
|
w={ width ? `${ width }px` : { base: `${ MOBILE_BANNER_WIDTH }px`, lg: `${ DESKTOP_BANNER_WIDTH }px` } }
|
|
h={ height ? `${ height }px` : { base: `${ MOBILE_BANNER_HEIGHT }px`, lg: `${ DESKTOP_BANNER_HEIGHT }px` } }
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default chakra(SpecifyBanner);
|