useLongRunningTransitionState.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { useEffect, useRef, useState } from 'react'
  2. import {
  3. getPersistedTransitionStartTime,
  4. getRemainingTransitionTimeMs,
  5. hoursToMilliseconds,
  6. MAX_PERSISTED_TRANSITION_AGE_HOURS,
  7. } from '@/lib/project-transition-state'
  8. interface UseLongRunningTransitionStateParams {
  9. storageKey: string | null
  10. thresholdMs: number
  11. }
  12. export const useLongRunningTransitionState = ({
  13. storageKey,
  14. thresholdMs,
  15. }: UseLongRunningTransitionStateParams) => {
  16. const [isTakingLongerThanExpected, setIsTakingLongerThanExpected] = useState(false)
  17. const fallbackStartTimeRef = useRef<number | null>(null)
  18. useEffect(() => {
  19. const now = Date.now()
  20. const fallbackStartTime = fallbackStartTimeRef.current ?? now
  21. fallbackStartTimeRef.current = fallbackStartTime
  22. const startTime = storageKey
  23. ? getPersistedTransitionStartTime(
  24. storageKey,
  25. now,
  26. hoursToMilliseconds(MAX_PERSISTED_TRANSITION_AGE_HOURS)
  27. )
  28. : fallbackStartTime
  29. const remainingThresholdMs = getRemainingTransitionTimeMs({
  30. startTimeMs: startTime,
  31. thresholdMs,
  32. now,
  33. })
  34. if (remainingThresholdMs === 0) {
  35. setIsTakingLongerThanExpected(true)
  36. return
  37. }
  38. setIsTakingLongerThanExpected(false)
  39. const timeoutId = setTimeout(() => setIsTakingLongerThanExpected(true), remainingThresholdMs)
  40. return () => clearTimeout(timeoutId)
  41. }, [storageKey, thresholdMs])
  42. return isTakingLongerThanExpected
  43. }