Skip to content

Commit

Permalink
feat(synapse-interface): ecotone and metis upgrade downtime, remove e…
Browse files Browse the repository at this point in the history
…th dencun (#2274)

* Add Ecotone Fork upgrade banner

* Add Metis Downtime banner

* Add Banner

* Remove ETH Dencun annoucements

* Add Ecotone Fork and Metis Upgrade Countdown Progress Bar to Bridge card

* Implement Bridge pauses for Metis and Ecotone downtime

* Bridge Pause feature working

* Add Ecotone Fork upgrade message

* Improve Ecotone Fork warning message

* Update Metis downtime message

* Simplify comparisons

* Update ecotone warning message

* Clean, prep for merge

* Update id

* Update EcotoneFork end time

* Move Events into Events folder

* Update Metis banner

* Update Ecotone Banner for EST

* Set times

* Rm import

* useEcotoneForkEventCountdownProgress to determine when to display progress

* useMetisDowntimeCountdownProgress

* Add isCurrentChainDisabled props

* Replace isBridgePaused with chain disabled prop

* Clean

* getCountdownTimeStatus

* Clean

* calculateTimeUntilTarget to be used in getCountdownTimeStatus

* Show hours remaining when over 90 min

* Update var naming

* Clean

* Update id to prevent conflicts

* Automatically show and remove Banner based on start / end time

* Refactor: AnnouncementBanner to use getCountdownTimeStatus

* Automate Banners to appear / disappear after start / end time respectively

* Keep in sync interval timers across all event countdown components

* Add comments

* adjust timings

---------

Co-authored-by: aureliusbtc <[email protected]>
  • Loading branch information
bigboydiamonds and aureliusbtc authored Mar 13, 2024
1 parent 60ca5cd commit f527ce5
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 169 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -54,11 +51,11 @@ export const AnnouncementBanner = ({
}
}, [showBanner, hasMounted])

if (!showBanner || !hasMounted || isComplete) return null
if (!showBanner || !hasMounted || !isStarted || isComplete) return null

return (
<div
className="flex items-center justify-center mx-auto lg:flex-row"
className="flex items-center justify-center mx-auto mb-3 lg:flex-row"
style={{
background:
'linear-gradient(310.65deg, rgba(172, 143, 255, 0.2) -17.9%, rgba(255, 0, 255, 0.2) 86.48%)',
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useMemo } from 'react'
import { LinearAnimatedProgressBar } from './LinearAnimatedProgressBar'
import { useIntervalTimer } from '@/utils/hooks/useIntervalTimer'

Expand All @@ -12,17 +11,14 @@ export const useEventCountdownProgressBar = (
EventCountdownProgressBar: JSX.Element
} => {
useIntervalTimer(60000)
const currentDate = new Date()
const currentTimeInSeconds = currentDate.getTime() / 1000
const startTimeInSeconds = Math.floor(startDate.getTime() / 1000)
const endTimeInSeconds = Math.floor(endDate.getTime() / 1000)

const timeRemainingInSeconds = endTimeInSeconds - currentTimeInSeconds
const timeRemainingInMinutes = Math.ceil(timeRemainingInSeconds / 60)
const { totalTimeRemainingInMinutes, hoursRemaining, isComplete, isPending } =
getCountdownTimeStatus(startDate, endDate)

const isStarted = currentTimeInSeconds >= startTimeInSeconds
const isComplete = timeRemainingInSeconds <= 0
const isPending = isStarted && !isComplete
const timeRemaining: string =
totalTimeRemainingInMinutes > 90
? `${hoursRemaining}h`
: `${totalTimeRemainingInMinutes}min`

let status: 'idle' | 'pending' | 'complete'

Expand All @@ -40,27 +36,27 @@ export const useEventCountdownProgressBar = (
EventCountdownProgressBar: (
<EventCountdownProgressBar
eventLabel={eventLabel}
startTime={startTimeInSeconds}
endTime={endTimeInSeconds}
startDate={startDate}
endDate={endDate}
timeRemaining={timeRemaining}
status={status}
timeRemaining={timeRemainingInMinutes}
/>
),
}
}

export const EventCountdownProgressBar = ({
eventLabel,
startTime,
endTime,
status,
startDate,
endDate,
timeRemaining,
status,
}: {
eventLabel: string
startTime: number
endTime: number
startDate: Date
endDate: Date
timeRemaining: string
status: 'idle' | 'pending' | 'complete'
timeRemaining: number
}) => {
if (status === 'pending') {
return (
Expand All @@ -73,14 +69,13 @@ export const EventCountdownProgressBar = ({
>
<div className="flex justify-between px-3 py-2">
<div>{eventLabel}</div>
<div>{timeRemaining}m remaining</div>
<div>{timeRemaining} remaining</div>
</div>
<div className="px-1">
<LinearAnimatedProgressBar
id="linear-animated-progress-bar"
startTime={startTime}
endTime={endTime}
status={status}
id="event-countdown-progress-bar"
startDate={startDate}
endDate={endDate}
/>
</div>
</div>
Expand All @@ -89,3 +84,69 @@ export const EventCountdownProgressBar = ({
return null
}
}

export const getCountdownTimeStatus = (startDate: Date, endDate: Date) => {
const currentDate = new Date()

const { daysRemaining, hoursRemaining, minutesRemaining, secondsRemaining } =
calculateTimeUntilTarget(endDate)

const currentTimeInSeconds = Math.floor(currentDate.getTime() / 1000)

const startTimeInSeconds = Math.floor(startDate.getTime() / 1000)
const endTimeInSeconds = Math.floor(endDate.getTime() / 1000)
const totalTimeInSeconds = endTimeInSeconds - startTimeInSeconds

const totalTimeElapsedInSeconds = currentTimeInSeconds - startTimeInSeconds
const totalTimeRemainingInSeconds = endTimeInSeconds - currentTimeInSeconds
const totalTimeRemainingInMinutes = Math.ceil(
totalTimeRemainingInSeconds / 60
)

const isStarted = currentTimeInSeconds >= startTimeInSeconds
const isComplete = totalTimeRemainingInSeconds <= 0
const isPending = isStarted && !isComplete

return {
currentDate,
currentTimeInSeconds,
startTimeInSeconds,
endTimeInSeconds,
totalTimeInSeconds,
totalTimeElapsedInSeconds,
totalTimeRemainingInSeconds,
totalTimeRemainingInMinutes,
daysRemaining,
hoursRemaining,
minutesRemaining,
secondsRemaining,
isStarted,
isComplete,
isPending,
}
}

const calculateTimeUntilTarget = (targetDate: Date) => {
const currentDate = new Date()

const timeDifference = targetDate.getTime() - currentDate.getTime()

const isComplete = timeDifference <= 0

const daysRemaining = Math.floor(timeDifference / (1000 * 60 * 60 * 24))
const hoursRemaining = Math.floor(
(timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
)
const minutesRemaining = Math.floor(
(timeDifference % (1000 * 60 * 60)) / (1000 * 60)
)
const secondsRemaining = Math.floor((timeDifference % (1000 * 60)) / 1000)

return {
daysRemaining,
hoursRemaining,
minutesRemaining,
secondsRemaining,
isComplete,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { AnnouncementBanner } from '../AnnouncementBanner'
import { WarningMessage } from '../../Warning'
import { useBridgeState } from '@/slices/bridge/hooks'
import { OPTIMISM, BASE } from '@/constants/chains/master'
import {
useEventCountdownProgressBar,
getCountdownTimeStatus,
} from '../EventCountdownProgressBar'
import { useIntervalTimer } from '@/utils/hooks/useIntervalTimer'

/**
* Start: 25 min prior to Ecotone Fork Upgrade Time @ (March 14, 00:00 UTC)
* End: 25 min after start of Ecotone Fork Upgrade Time
*/
export const ECOTONE_FORK_BANNERS_START = new Date(
Date.UTC(2024, 2, 13, 23, 20, 0)
)
export const ECOTONE_FORK_START_DATE = new Date(
Date.UTC(2024, 2, 13, 23, 35, 0)
)
export const ECOTONE_FORK_END_DATE = new Date(Date.UTC(2024, 2, 14, 0, 25, 0))

export const EcotoneForkUpgradeBanner = () => {
const { isComplete } = getCountdownTimeStatus(
ECOTONE_FORK_BANNERS_START,
ECOTONE_FORK_END_DATE
)

useIntervalTimer(60000, isComplete)

return (
<AnnouncementBanner
bannerId="03142024-ecotone-fork"
bannerContents={
<div className="flex flex-col justify-center space-y-1 text-center">
<div>
Optimism + Base Bridging will be paused 10 minutes ahead of Ecotone
(March 14, 00:00 UTC, 20:00 EST).
</div>
<div>Will be back online shortly following the network upgrade.</div>
</div>
}
startDate={ECOTONE_FORK_BANNERS_START}
endDate={ECOTONE_FORK_END_DATE}
/>
)
}

export const EcotoneForkWarningMessage = () => {
const { fromChainId, toChainId } = useBridgeState()

const isChainOptimism = [fromChainId, toChainId].includes(OPTIMISM.id)
const isChainBase = [fromChainId, toChainId].includes(BASE.id)

if (isChainOptimism || isChainBase) {
return (
<WarningMessage
message={
<>
<p>
Optimism Chain and Base Chain bridging are paused until the
Ecotone Fork upgrade completes.
</p>
</>
}
/>
)
} 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,
}
}
Loading

0 comments on commit f527ce5

Please sign in to comment.