use-detached-orphan-detection.ts 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { useLayoutContext } from '@/shared/context/layout-context'
  2. import { useEffect, useRef, useState } from 'react'
  3. type OrphanState = 'connecting' | 'orphan' | 'not-orphan'
  4. const ORPHAN_UI_TIMEOUT_MS = 5000
  5. export default function useDetachedOrphanDetection(): OrphanState {
  6. const { detachRole, detachIsLinked } = useLayoutContext()
  7. const uiTimeoutRef = useRef<number>()
  8. const [longTimeOrphan, setLongTimeOrphan] = useState(false)
  9. const orphaned = !detachIsLinked && detachRole === 'detached'
  10. useEffect(() => {
  11. if (uiTimeoutRef.current) {
  12. window.clearTimeout(uiTimeoutRef.current)
  13. }
  14. if (orphaned) {
  15. uiTimeoutRef.current = window.setTimeout(() => {
  16. setLongTimeOrphan(true)
  17. }, ORPHAN_UI_TIMEOUT_MS)
  18. } else {
  19. setLongTimeOrphan(false)
  20. }
  21. return () => {
  22. if (uiTimeoutRef.current) {
  23. window.clearTimeout(uiTimeoutRef.current)
  24. }
  25. }
  26. }, [orphaned])
  27. if (!orphaned) {
  28. // not detached, or detached but linked
  29. return 'not-orphan'
  30. }
  31. if (longTimeOrphan) {
  32. return 'orphan'
  33. } else if (orphaned) {
  34. return 'connecting'
  35. } else {
  36. return 'not-orphan'
  37. }
  38. }