Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 32x 32x 32x 32x 32x 32x 32x 32x 32x 22x 3x 3x 32x 1x 1x | import { useFeatureValue } from "@growthbook/growthbook-react";
import { useAuthContext } from "features/auth/AuthProvider";
import { usePersistedState } from "platform/usePersistedState";
import { useEffect, useState } from "react";
import { useIsClient } from "utils/hooks";
import CelebrationBanner from "./CelebrationBanner";
import CelebrationOverlay from "./CelebrationOverlay";
import { CELEBRATION_100K_FLAG, CELEBRATION_100K_SEEN_KEY } from "./constants";
import { useMemberClusters } from "./useMemberClusters";
interface Celebration100kProps {
/** Play the overlay by itself the first time this device opens the page */
autoPlay?: boolean;
}
/**
* The 100k members celebration for logged-in members, switched on and off with a feature flag for the week.
* Shows a one-row banner with a replay, and (when `autoPlay` is set) plays the overlay once per device.
*/
export default function Celebration100k({ autoPlay = false }: Celebration100kProps) {
const isFlagOn = useFeatureValue(CELEBRATION_100K_FLAG, false);
const { authState } = useAuthContext();
const isEnabled = isFlagOn && authState.authenticated;
// Storage is only readable in the browser, so render nothing until then to avoid a hydration mismatch
const isClient = useIsClient();
const [hasSeen, setHasSeen] = usePersistedState(CELEBRATION_100K_SEEN_KEY, false);
const [isOpen, setIsOpen] = useState(false);
// Load the map data before opening, so slow connections don't sit on an empty map
const willAutoPlay = isEnabled && isClient && autoPlay && !hasSeen;
const { isSuccess: membersLoaded } = useMemberClusters(willAutoPlay);
useEffect(() => {
// If the data doesn't load (slow or dropped connection), it autoplays on a later visit instead
if (!willAutoPlay || !membersLoaded) return;
// Marked as seen as soon as it starts, so closing early or reloading doesn't play it again
setHasSeen(true);
setIsOpen(true);
}, [willAutoPlay, membersLoaded, setHasSeen]);
if (!isEnabled || !isClient) return null;
return (
<>
{(hasSeen || !autoPlay) && <CelebrationBanner onReplay={() => setIsOpen(true)} />}
<CelebrationOverlay open={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}
|