mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
import Script from 'next/script';
|
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
|
|
import config from 'configs/app';
|
|
import { cn } from 'lib/utils/cn';
|
|
import { Skeleton } from '@luxfi/ui/skeleton';
|
|
|
|
const adTextFeature = config.features.adsText;
|
|
|
|
const AD_LOAD_TIMEOUT = 1_000;
|
|
|
|
type Status = 'loading' | 'loaded' | 'empty';
|
|
|
|
const SevioTextAd = ({ className }: { className?: string }) => {
|
|
const [ status, setStatus ] = React.useState<Status>('loading');
|
|
const adRef = useRef<HTMLDivElement>(null);
|
|
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
|
|
useEffect(() => {
|
|
if (!adTextFeature.isEnabled) {
|
|
return;
|
|
}
|
|
const { zone, adType, inventoryId, accountId } = adTextFeature.sevio;
|
|
window.sevioads = window.sevioads || [];
|
|
window.sevioads.push([ { zone, adType, inventoryId, accountId } ]);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const node = adRef.current;
|
|
if (!node) {
|
|
return;
|
|
}
|
|
|
|
const observer = new MutationObserver(() => {
|
|
if (node.childNodes.length > 0) {
|
|
clearTimeout(timeoutRef.current);
|
|
setStatus('loaded');
|
|
observer.disconnect();
|
|
}
|
|
});
|
|
|
|
observer.observe(node, { childList: true });
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
clearTimeout(timeoutRef.current);
|
|
};
|
|
}, []);
|
|
|
|
const handleScriptLoad = useCallback(() => {
|
|
timeoutRef.current = setTimeout(() => {
|
|
setStatus((prev) => prev === 'loading' ? 'empty' : prev);
|
|
}, AD_LOAD_TIMEOUT);
|
|
}, []);
|
|
|
|
const handleScriptError = useCallback(() => {
|
|
setStatus('empty');
|
|
}, []);
|
|
|
|
if (!adTextFeature.isEnabled || status === 'empty') {
|
|
return null;
|
|
}
|
|
|
|
const { zone } = adTextFeature.sevio;
|
|
|
|
return (
|
|
<>
|
|
{ status === 'loading' && (
|
|
<Skeleton
|
|
loading
|
|
className={ cn(className, 'h-12 lg:h-6') }
|
|
w="100%"
|
|
flexGrow={ 1 }
|
|
maxW="800px"
|
|
display="block"
|
|
/>
|
|
) }
|
|
<div
|
|
className={ cn(
|
|
status === 'loaded' ? className : undefined,
|
|
status === 'loaded' ? 'text-xs lg:text-base' : 'hidden',
|
|
'text-[var(--color-text-secondary)] lg:text-[var(--color-text-primary)]',
|
|
) }
|
|
style={ status !== 'loaded' ? { display: 'none' } : undefined }
|
|
>
|
|
<style>{ `
|
|
.sevioads * { font-family: inherit; font-size: inherit; }
|
|
.sevioads strong { color: inherit; }
|
|
.sevioads a { color: var(--color-link-primary); }
|
|
.sevioads a:hover { color: var(--color-link-primary-hover); }
|
|
` }</style>
|
|
<Script
|
|
strategy="lazyOnload"
|
|
src="https://cdn.adx.ws/scripts/loader.js"
|
|
onLoad={ handleScriptLoad }
|
|
onError={ handleScriptError }
|
|
/>
|
|
<div ref={ adRef } className="sevioads" data-zone={ zone }/>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default SevioTextAd;
|