use-detach-layout.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { useCallback, useState, useEffect } from 'react'
  2. import { useDetachContext } from '../context/detach-context'
  3. import getMeta from '../../utils/meta'
  4. import { buildUrlWithDetachRole } from '../utils/url-helper'
  5. const debugPdfDetach = getMeta('ol-debugPdfDetach')
  6. export default function useDetachLayout() {
  7. const {
  8. role,
  9. setRole,
  10. broadcastEvent,
  11. addEventHandler,
  12. deleteEventHandler,
  13. } = useDetachContext()
  14. const [mode, setMode] = useState(() => {
  15. if (role === 'detacher') {
  16. return 'detaching'
  17. }
  18. if (role === 'detached') {
  19. return 'orphan'
  20. }
  21. })
  22. useEffect(() => {
  23. if (debugPdfDetach) {
  24. console.log('Effect', { mode })
  25. }
  26. }, [mode])
  27. const reattach = useCallback(() => {
  28. broadcastEvent('reattach')
  29. setRole(null)
  30. setMode(null)
  31. }, [setRole, setMode, broadcastEvent])
  32. const detach = useCallback(() => {
  33. setRole('detacher')
  34. setMode('detaching')
  35. window.open(buildUrlWithDetachRole('detached'), '_blank')
  36. }, [setRole, setMode])
  37. const handleEventForDetacherFromDetached = useCallback(
  38. message => {
  39. switch (message.event) {
  40. case 'connected':
  41. broadcastEvent('up')
  42. setMode('detacher')
  43. break
  44. case 'up':
  45. setMode('detacher')
  46. break
  47. case 'closed':
  48. setMode(null)
  49. break
  50. }
  51. },
  52. [setMode, broadcastEvent]
  53. )
  54. const handleEventForDetachedFromDetacher = useCallback(
  55. message => {
  56. switch (message.event) {
  57. case 'connected':
  58. broadcastEvent('up')
  59. setMode('detached')
  60. break
  61. case 'up':
  62. setMode('detached')
  63. break
  64. case 'closed':
  65. setMode('orphan')
  66. break
  67. case 'reattach':
  68. window.close()
  69. break
  70. }
  71. },
  72. [setMode, broadcastEvent]
  73. )
  74. const handleEventFromSelf = useCallback(
  75. message => {
  76. switch (message.event) {
  77. case 'closed':
  78. broadcastEvent('up')
  79. break
  80. }
  81. },
  82. [broadcastEvent]
  83. )
  84. const handleEvent = useCallback(
  85. message => {
  86. if (role === 'detacher') {
  87. if (message.role === 'detacher') {
  88. handleEventFromSelf(message)
  89. } else if (message.role === 'detached') {
  90. handleEventForDetacherFromDetached(message)
  91. }
  92. } else if (role === 'detached') {
  93. if (message.role === 'detacher') {
  94. handleEventForDetachedFromDetacher(message)
  95. } else if (message.role === 'detached') {
  96. handleEventFromSelf(message)
  97. }
  98. }
  99. },
  100. [
  101. role,
  102. handleEventForDetacherFromDetached,
  103. handleEventForDetachedFromDetacher,
  104. handleEventFromSelf,
  105. ]
  106. )
  107. useEffect(() => {
  108. addEventHandler(handleEvent)
  109. return () => deleteEventHandler(handleEvent)
  110. }, [addEventHandler, deleteEventHandler, handleEvent])
  111. return {
  112. reattach,
  113. detach,
  114. mode,
  115. role,
  116. }
  117. }