feat: spinner with timer

This commit is contained in:
enes 2025-01-14 17:48:15 +01:00
parent 5d479102d4
commit ce27515bfe
2 changed files with 54 additions and 5 deletions

View File

@ -1,3 +1,4 @@
import { PropsWithChildren, useEffect, useMemo, useState } from 'react'
import { useNavigation } from 'react-router-dom'
import styles from '../../styles/loadingSpinner.module.scss'
@ -5,9 +6,7 @@ interface Props {
desc: string
}
export const LoadingSpinner = (props: Props) => {
const { desc } = props
export const LoadingSpinner = ({ desc }: Props) => {
return (
<div className={styles.loadingSpinnerOverlay}>
<div className={styles.loadingSpinnerContainer}>
@ -28,3 +27,51 @@ export const RouterLoadingSpinner = () => {
return <LoadingSpinner desc={`${desc}...`} />
}
interface TimerLoadingSpinner {
timeoutMs?: number
countdownMs?: number
}
export const TimerLoadingSpinner = ({
timeoutMs = 10000,
countdownMs = 30000,
children
}: PropsWithChildren<TimerLoadingSpinner>) => {
const [show, setShow] = useState(false)
const [timer, setTimer] = useState(
Math.floor((countdownMs - timeoutMs) / 1000)
)
const startTime = useMemo(() => Date.now(), [])
useEffect(() => {
let interval: number
const timeout = window.setTimeout(() => {
setShow(true)
interval = window.setInterval(() => {
const time = Date.now() - startTime
const diff = Math.max(0, countdownMs - time)
setTimer(Math.floor(diff / 1000))
}, 1000)
}, timeoutMs)
return () => {
clearTimeout(timeout)
clearInterval(interval)
}
}, [countdownMs, startTime, timeoutMs])
return (
<div className={styles.loadingSpinnerOverlay}>
<div className={styles.loadingSpinnerContainer}>
<div className={styles.loadingSpinner}></div>
{children}
{show && (
<>
<div>You can try again in {timer}s...</div>
</>
)}
</div>
</div>
)
}

View File

@ -1,4 +1,4 @@
import { LoadingSpinner } from 'components/LoadingSpinner'
import { LoadingSpinner, TimerLoadingSpinner } from 'components/LoadingSpinner'
import { ModForm } from 'components/ModForm'
import { ProfileSection } from 'components/ProfileSection'
import { useAppSelector } from 'hooks'
@ -24,7 +24,9 @@ export const SubmitModPage = () => {
<LoadingSpinner desc='Fetching mod details from relays' />
)}
{navigation.state === 'submitting' && (
<LoadingSpinner desc='Publishing mod to relays' />
<TimerLoadingSpinner timeoutMs={10000} countdownMs={30000}>
Publishing mod to relays
</TimerLoadingSpinner>
)}
<ModForm />
</div>