import type { FC } from 'react' import type { Banner as BannerType } from '@/models/app' import * as React from 'react' import { useEffect, useMemo, useRef, useState } from 'react' import { trackEvent } from '@/app/components/base/amplitude' import { Carousel, useCarousel } from '@/app/components/base/carousel' import { useSelector } from '@/context/app-context' import { useLocale } from '@/context/i18n' import { useGetBanners } from '@/service/use-explore' import Loading from '../../base/loading' import { BannerItem } from './banner-item' const AUTOPLAY_DELAY = 5000 const MIN_LOADING_HEIGHT = 168 const RESIZE_DEBOUNCE_DELAY = 50 const LoadingState: FC = () => (
) type BannerImpressionTrackerProps = { banners: BannerType[] accountId?: string language: string trackedBannerIdsRef: React.MutableRefObject> } const BannerImpressionTracker: FC = ({ banners, accountId, language, trackedBannerIdsRef, }) => { const { selectedIndex } = useCarousel() useEffect(() => { if (!accountId) return const currentBanner = banners[selectedIndex] if (!currentBanner || trackedBannerIdsRef.current.has(currentBanner.id)) return trackEvent('explore_banner_impression', { banner_id: currentBanner.id, title: currentBanner.content.title, sort: selectedIndex + 1, link: currentBanner.link, page: 'explore', language, account_id: accountId, event_time: Date.now(), }) trackedBannerIdsRef.current.add(currentBanner.id) }, [accountId, banners, language, selectedIndex, trackedBannerIdsRef]) return null } const Banner: FC = () => { const locale = useLocale() const { data: banners, isLoading, isError } = useGetBanners(locale) const accountId = useSelector(s => s.userProfile.id) const [isHovered, setIsHovered] = useState(false) const [isResizing, setIsResizing] = useState(false) const resizeTimerRef = useRef(null) const trackedBannerIdsRef = useRef>(new Set()) const enabledBanners = useMemo( () => banners?.filter(banner => banner.status === 'enabled') ?? [], [banners], ) const isPaused = isHovered || isResizing // Handle window resize to pause animation useEffect(() => { const handleResize = () => { setIsResizing(true) if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current) resizeTimerRef.current = setTimeout(() => { setIsResizing(false) }, RESIZE_DEBOUNCE_DELAY) } window.addEventListener('resize', handleResize) return () => { window.removeEventListener('resize', handleResize) if (resizeTimerRef.current) clearTimeout(resizeTimerRef.current) } }, []) if (isLoading) return if (isError || enabledBanners.length === 0) return null return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > {enabledBanners.map((banner, index) => ( ))} ) } export default React.memo(Banner)