import SideNav from './SideNav' import { Fragment, ReactNode, useCallback, useEffect, useMemo, useState, } from 'react' import { ArrowPathIcon, ChevronRightIcon } from '@heroicons/react/20/solid' import { useViewport } from '../hooks/useViewport' import { breakpoints } from '../utils/theme' import mangoStore from '@store/mangoStore' import BottomBar from './mobile/BottomBar' import BounceLoader from './shared/BounceLoader' import TopBar from './TopBar' import useLocalStorageState from '../hooks/useLocalStorageState' import { ACCEPT_TERMS_KEY, SIDEBAR_COLLAPSE_KEY } from '../utils/constants' import { useWallet } from '@solana/wallet-adapter-react' import SuccessParticles from './shared/SuccessParticles' import { tsParticles } from 'tsparticles-engine' import { loadFull } from 'tsparticles' import useInterval from './shared/useInterval' import { Transition } from '@headlessui/react' import { useTranslation } from 'next-i18next' import TermsOfUseModal from './modals/TermsOfUseModal' import { ttCommons, ttCommonsExpanded, ttCommonsMono } from 'utils/fonts' import PromoBanner from './rewards/PromoBanner' import { useRouter } from 'next/router' export const sideBarAnimationDuration = 300 const termsLastUpdated = 1679441610978 const Layout = ({ children }: { children: ReactNode }) => { const [isCollapsed, setIsCollapsed] = useLocalStorageState( SIDEBAR_COLLAPSE_KEY, false ) const { width } = useViewport() const { asPath } = useRouter() useEffect(() => { if (width < breakpoints.xl) { setIsCollapsed(true) } }, [width]) useEffect(() => { const animationFrames = 15 for (let x = 1; x <= animationFrames; x++) { setTimeout(() => { window.dispatchEvent(new Event('resize')) }, (sideBarAnimationDuration / animationFrames) * x) } }, [isCollapsed]) const handleToggleSidebar = () => { setIsCollapsed(!isCollapsed) } const particlesInit = useCallback(async () => { await loadFull(tsParticles) }, []) useEffect(() => { particlesInit() }, []) return (
{/* note: overflow-x-hidden below prevents position sticky from working in activity feed */}
{asPath !== '/rewards' ? : null} {children}
) } export default Layout const MangoAccountLoadingOverlay = () => { const { connected } = useWallet() const loadingMangoAccount = mangoStore((s) => s.mangoAccount.initialLoad) return ( <> {connected && loadingMangoAccount ? (
) : null} ) } const TermsOfUse = () => { const { connected } = useWallet() const [acceptTerms, setAcceptTerms] = useLocalStorageState( ACCEPT_TERMS_KEY, '' ) const showTermsOfUse = useMemo(() => { return (!acceptTerms || acceptTerms < termsLastUpdated) && connected }, [acceptTerms, connected]) return ( <> {showTermsOfUse ? ( setAcceptTerms(Date.now())} /> ) : null} ) } function DeployRefreshManager(): JSX.Element | null { const { t } = useTranslation('common') const [newBuildAvailable, setNewBuildAvailable] = useState(false) useInterval(async () => { const response = await fetch('/api/build-id') const { buildId } = await response.json() if (buildId && process.env.BUILD_ID && buildId !== process.env.BUILD_ID) { // There's a new version deployed that we need to load setNewBuildAvailable(true) } }, 300000) return ( ) }