diff --git a/packages/synapse-interface/components/Maintenance/AnnouncementBanner.tsx b/packages/synapse-interface/components/Maintenance/AnnouncementBanner.tsx index 42dc33dc97..377bcfadcf 100644 --- a/packages/synapse-interface/components/Maintenance/AnnouncementBanner.tsx +++ b/packages/synapse-interface/components/Maintenance/AnnouncementBanner.tsx @@ -1,7 +1,10 @@ import { useState, useEffect } from 'react' +import { getCountdownTimeStatus } from './EventCountdownProgressBar' /** - * Reusable Annoucement Banner with custom Start/End Time + * Reusable automated Announcement Banner with custom Start/End Time + * Will automatically appear after Start time + * Will automatically disappear after End time * @param bannerId: store in $MMDDYYYY-$BANNER_NAME format (e.g 03132024-ETH-DENCUN) * @param bannerContents: contents to display in banner * @param startDate: start date to show banner @@ -18,15 +21,9 @@ export const AnnouncementBanner = ({ startDate: Date endDate: Date }) => { + const { isStarted, isComplete } = getCountdownTimeStatus(startDate, endDate) const [hasMounted, setHasMounted] = useState(false) - const [showBanner, setShowBanner] = useState(false) - - const currentDate = new Date() - - const isStarted = - Math.floor(currentDate.getTime()) - Math.floor(startDate.getTime()) >= 0 - const isComplete = - Math.floor(currentDate.getTime()) - Math.floor(endDate.getTime()) >= 0 + const [showBanner, setShowBanner] = useState(true) useEffect(() => { setHasMounted(true) @@ -54,11 +51,11 @@ export const AnnouncementBanner = ({ } }, [showBanner, hasMounted]) - if (!showBanner || !hasMounted || isComplete) return null + if (!showBanner || !hasMounted || !isStarted || isComplete) return null return (
+ Optimism Chain and Base Chain bridging are paused until the + Ecotone Fork upgrade completes. +
+ > + } + /> + ) + } else return null +} + +export const useEcotoneForkCountdownProgress = () => { + const { fromChainId, toChainId } = useBridgeState() + + const isChainOptimism = [fromChainId, toChainId].includes(OPTIMISM.id) + const isChainBase = [fromChainId, toChainId].includes(BASE.id) + + const { + isPending: isEcotoneForkUpgradePending, + EventCountdownProgressBar: EcotoneForkCountdownProgressBar, + } = useEventCountdownProgressBar( + 'Ecotone Fork upgrade in progress', + ECOTONE_FORK_START_DATE, + ECOTONE_FORK_END_DATE + ) + + return { + isEcotoneForkUpgradePending, + isCurrentChainDisabled: + (isChainOptimism || isChainBase) && isEcotoneForkUpgradePending, + EcotoneForkCountdownProgressBar: + isChainOptimism || isChainBase ? EcotoneForkCountdownProgressBar : null, + } +} diff --git a/packages/synapse-interface/components/Maintenance/Events/MetisUpgrade.tsx b/packages/synapse-interface/components/Maintenance/Events/MetisUpgrade.tsx new file mode 100644 index 0000000000..20272264af --- /dev/null +++ b/packages/synapse-interface/components/Maintenance/Events/MetisUpgrade.tsx @@ -0,0 +1,90 @@ +import { AnnouncementBanner } from '../AnnouncementBanner' +import { WarningMessage } from '../../Warning' +import { useBridgeState } from '@/slices/bridge/hooks' +import { METIS } from '@/constants/chains/master' +import { useEventCountdownProgressBar } from '../EventCountdownProgressBar' +import { useIntervalTimer } from '@/utils/hooks/useIntervalTimer' +import { getCountdownTimeStatus } from '../EventCountdownProgressBar' + +/** + * Start: 30 min prior to Metis Chain Downtime @ (March 14, 02:00 UTC) + * End: 12 hours after start of Metis Chain Downtime + */ +export const METIS_DOWNTIME_BANNERS_START = new Date( + Date.UTC(2024, 2, 14, 1, 30, 0) +) +export const METIS_DOWNTIME_START_DATE = new Date( + Date.UTC(2024, 2, 14, 1, 45, 0) +) +export const METIS_DOWNTIME_END_DATE = new Date( + Date.UTC(2024, 2, 14, 13, 30, 0) +) + +export const MetisDowntimeBanner = () => { + const { isComplete } = getCountdownTimeStatus( + METIS_DOWNTIME_BANNERS_START, + METIS_DOWNTIME_END_DATE + ) + + useIntervalTimer(60000, isComplete) + + return ( ++ Metis Chain bridging is paused until the Metis upgrade completes. +
+ > + } + /> + ) + } else return null +} + +export const useMetisDowntimeCountdownProgress = () => { + const { fromChainId, toChainId } = useBridgeState() + + const isChainMetis = [fromChainId, toChainId].includes(METIS.id) + + const { + isPending: isMetisUpgradePending, + EventCountdownProgressBar: MetisUpgradeCountdownProgressBar, + } = useEventCountdownProgressBar( + 'Metis upgrade in progress', + METIS_DOWNTIME_START_DATE, + METIS_DOWNTIME_END_DATE + ) + + return { + isMetisUpgradePending, + isCurrentChainDisabled: isChainMetis && isMetisUpgradePending, + MetisUpgradeCountdownProgressBar: isChainMetis + ? MetisUpgradeCountdownProgressBar + : null, + } +} diff --git a/packages/synapse-interface/components/Maintenance/LinearAnimatedProgressBar.tsx b/packages/synapse-interface/components/Maintenance/LinearAnimatedProgressBar.tsx index d2c90fbe7b..955b932afc 100644 --- a/packages/synapse-interface/components/Maintenance/LinearAnimatedProgressBar.tsx +++ b/packages/synapse-interface/components/Maintenance/LinearAnimatedProgressBar.tsx @@ -1,36 +1,33 @@ import { memo } from 'react' -import { getTimeMinutesBeforeNow } from '@/utils/time' +import { getCountdownTimeStatus } from './EventCountdownProgressBar' /** * @param id unique identifier for progress bar instance * @param startTime start time in unix seconds * @param endTime end time in unix seconds - * @param status progress status */ export const LinearAnimatedProgressBar = memo( ({ id, - startTime, - endTime, - status, + startDate, + endDate, }: { id: string - startTime: number - endTime: number - status: 'idle' | 'pending' | 'complete' + startDate: Date + endDate: Date }) => { - const currentTime = Math.floor(getTimeMinutesBeforeNow(0)) - const elapsedTimeInSeconds = currentTime - startTime - const remainingTimeInSeconds = endTime - currentTime - const totalTimeInSeconds = endTime - startTime + const { + totalTimeInSeconds, + totalTimeElapsedInSeconds, + totalTimeRemainingInSeconds, + isComplete, + } = getCountdownTimeStatus(startDate, endDate) const percentElapsed = Math.floor( - (elapsedTimeInSeconds / totalTimeInSeconds) * 100 + (totalTimeElapsedInSeconds / totalTimeInSeconds) * 100 ) - const isComplete = status === 'complete' - - let duration = isComplete ? 0.5 : remainingTimeInSeconds + let duration = isComplete ? 0.5 : totalTimeRemainingInSeconds const synapsePurple = 'hsl(265deg 100% 75%)' const tailwindGreen400 = 'rgb(74 222 128)' @@ -40,7 +37,7 @@ export const LinearAnimatedProgressBar = memo( return (