use-detach-state.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { useEffect, useState, useCallback } from 'react'
  2. import { useDetachContext } from '../context/detach-context'
  3. import getMeta from '../../utils/meta'
  4. const debugPdfDetach = getMeta('ol-debugPdfDetach')
  5. export default function useDetachState(
  6. key,
  7. defaultValue,
  8. senderRole,
  9. targetRole
  10. ) {
  11. const [value, setValue] = useState(defaultValue)
  12. const {
  13. role,
  14. broadcastEvent,
  15. lastDetachedConnectedAt,
  16. addEventHandler,
  17. deleteEventHandler,
  18. } = useDetachContext()
  19. const eventName = `state-${key}`
  20. // lastDetachedConnectedAt is added as a dependency in order to re-broadcast
  21. // all states when a new detached tab connects
  22. useEffect(() => {
  23. if (role === senderRole) {
  24. broadcastEvent(eventName, { value })
  25. }
  26. }, [
  27. role,
  28. senderRole,
  29. eventName,
  30. value,
  31. broadcastEvent,
  32. lastDetachedConnectedAt,
  33. ])
  34. const handleStateEvent = useCallback(
  35. message => {
  36. if (message.event !== eventName) {
  37. return
  38. }
  39. if (role !== targetRole) {
  40. return
  41. }
  42. if (debugPdfDetach) {
  43. console.log(`Set ${message.data.value} for ${eventName}`)
  44. }
  45. setValue(message.data.value)
  46. },
  47. [role, targetRole, eventName, setValue]
  48. )
  49. useEffect(() => {
  50. addEventHandler(handleStateEvent)
  51. return () => deleteEventHandler(handleStateEvent)
  52. }, [addEventHandler, deleteEventHandler, handleStateEvent])
  53. return [value, setValue]
  54. }