diff --git a/components/drops/view/BoostedDropCard.tsx b/components/drops/view/BoostedDropCard.tsx index 8343bd735b..bbc3173629 100644 --- a/components/drops/view/BoostedDropCard.tsx +++ b/components/drops/view/BoostedDropCard.tsx @@ -11,6 +11,7 @@ import { buildProcessedContent } from "@/components/waves/drops/media-utils"; import type { ApiDrop } from "@/generated/models/ApiDrop"; import { convertApiDropToExtendedDrop } from "@/helpers/waves/drop.helpers"; import { useDropBoostMutation } from "@/hooks/drops/useDropBoostMutation"; +import { ChevronRightIcon } from "@heroicons/react/24/outline"; import Image from "next/image"; import { memo, useCallback, useContext, useMemo } from "react"; @@ -70,14 +71,12 @@ const BoostedDropCard = memo( tabIndex={0} >
- {/* Rank badge */}
{rank}
- {/* Author avatar */}
{resolvedPfp ? ( - {/* Content */}
- {/* Boost count - clickable toggle */} - {/* Arrow indicator */} - - - +
); diff --git a/components/home/HomePageContent.tsx b/components/home/HomePageContent.tsx index 24e78a6171..c4726d38c9 100644 --- a/components/home/HomePageContent.tsx +++ b/components/home/HomePageContent.tsx @@ -1,52 +1,18 @@ "use client"; -import { useState, useRef, useCallback } from "react"; -import type { ExtendedDrop } from "@/helpers/waves/drop.helpers"; -import SubmissionCarousel, { - type SubmissionCarouselHandle, -} from "./carousel/SubmissionCarousel"; -import CarouselActiveItemVote from "./carousel/CarouselActiveItemVote"; -import CarouselActiveItemDetails from "./carousel/CarouselActiveItemDetails"; +import SubmissionCarouselSection from "./SubmissionCarouselSection"; import { NowMintingSection } from "./now-minting"; import { NextMintLeadingSection } from "./next-mint-leading"; import { BoostedSection } from "./boosted"; import { ExploreWavesSection } from "./explore-waves"; -import { CarouselHeader, HeroHeader } from "./hero"; +import { HeroHeader } from "./hero"; export default function HomePageContent() { - const [activeDrop, setActiveDrop] = useState(null); - const carouselRef = useRef(null); - - const pauseAutoplay = useCallback( - () => carouselRef.current?.pauseAutoplay(), - [] - ); - const resumeAutoplay = useCallback( - () => carouselRef.current?.resumeAutoplay(), - [] - ); - return (
-
- -
- -
- {activeDrop && } -
-
- -
+
diff --git a/components/home/SubmissionCarouselSection.tsx b/components/home/SubmissionCarouselSection.tsx new file mode 100644 index 0000000000..0bc32d532c --- /dev/null +++ b/components/home/SubmissionCarouselSection.tsx @@ -0,0 +1,94 @@ +"use client"; + +import { useCallback, useRef, useState } from "react"; +import type { ExtendedDrop } from "@/helpers/waves/drop.helpers"; +import CarouselActiveItemDetails from "./carousel/CarouselActiveItemDetails"; +import CarouselActiveItemVote from "./carousel/CarouselActiveItemVote"; +import SubmissionCarousel, { + type SubmissionCarouselHandle, +} from "./carousel/SubmissionCarousel"; +import { CarouselHeader } from "./hero"; + +export default function SubmissionCarouselSection() { + const [activeDrop, setActiveDrop] = useState(null); + const carouselRef = useRef(null); + const isPointerInsideRef = useRef(false); + const isVotingModalOpenRef = useRef(false); + const isAutoplayPausedRef = useRef(false); + + const updateAutoplayState = useCallback(() => { + const shouldPause = + isPointerInsideRef.current || isVotingModalOpenRef.current; + if (shouldPause === isAutoplayPausedRef.current) { + return; + } + isAutoplayPausedRef.current = shouldPause; + if (shouldPause) { + carouselRef.current?.pauseAutoplay(); + } else { + carouselRef.current?.resumeAutoplay(); + } + }, []); + + const handlePointerEnter = useCallback(() => { + isPointerInsideRef.current = true; + updateAutoplayState(); + }, [updateAutoplayState]); + + const handlePointerMove = useCallback(() => { + if (isPointerInsideRef.current) { + return; + } + isPointerInsideRef.current = true; + updateAutoplayState(); + }, [updateAutoplayState]); + + const handlePointerLeave = useCallback(() => { + isPointerInsideRef.current = false; + updateAutoplayState(); + }, [updateAutoplayState]); + + const handleVoteOpen = useCallback(() => { + isVotingModalOpenRef.current = true; + updateAutoplayState(); + }, [updateAutoplayState]); + + const handleVoteClose = useCallback(() => { + isVotingModalOpenRef.current = false; + updateAutoplayState(); + }, [updateAutoplayState]); + + const handleCarouselRef = useCallback( + (instance: SubmissionCarouselHandle | null) => { + carouselRef.current = instance; + updateAutoplayState(); + }, + [updateAutoplayState] + ); + + return ( +
+
+ +
+ +
+ {activeDrop && ( + + )} +
+ +
+ ); +} diff --git a/components/home/boosted/BoostedDropCardHome.tsx b/components/home/boosted/BoostedDropCardHome.tsx index 4d9a55e690..28b120ae39 100644 --- a/components/home/boosted/BoostedDropCardHome.tsx +++ b/components/home/boosted/BoostedDropCardHome.tsx @@ -9,7 +9,7 @@ import ContentDisplay from "@/components/waves/drops/ContentDisplay"; import { buildProcessedContent } from "@/components/waves/drops/media-utils"; import type { ApiDrop } from "@/generated/models/ApiDrop"; import { getScaledImageUri, ImageScale } from "@/helpers/image.helpers"; -import { LinkIcon } from "@heroicons/react/24/outline"; +import { LinkIcon, Square2StackIcon } from "@heroicons/react/24/outline"; import Link from "next/link"; import { memo, useCallback, useMemo } from "react"; @@ -71,6 +71,10 @@ const BoostedDropCardHome = memo(
{media ? (
+