use-detach-state.js 1.5 KB

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