2021-11-30 09:54:14 -05:00
|
|
|
import { useEffect, useState, useCallback } from 'react'
|
|
|
|
import { useDetachContext } from '../context/detach-context'
|
|
|
|
import getMeta from '../../utils/meta'
|
|
|
|
|
|
|
|
const debugPdfDetach = getMeta('ol-debugPdfDetach')
|
|
|
|
|
2023-01-09 09:33:43 -05:00
|
|
|
export type DetachRole = 'detacher' | 'detached'
|
|
|
|
export type DetachTargetRole<T extends DetachRole> = T extends 'detacher'
|
|
|
|
? 'detached'
|
|
|
|
: 'detacher'
|
|
|
|
export type Message<DataArgs = unknown> = {
|
|
|
|
event: `${'action' | 'state'}-${string}`
|
|
|
|
data: {
|
|
|
|
args: DataArgs[]
|
|
|
|
value: unknown
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function useDetachState<S extends DetachRole, T extends DetachTargetRole<S>>(
|
|
|
|
key: string,
|
|
|
|
defaultValue: unknown,
|
|
|
|
senderRole: S,
|
|
|
|
targetRole: T
|
|
|
|
): [unknown, React.Dispatch<unknown>] {
|
2021-11-30 09:54:14 -05:00
|
|
|
const [value, setValue] = useState(defaultValue)
|
|
|
|
|
2022-03-31 07:22:36 -04:00
|
|
|
const {
|
|
|
|
role,
|
|
|
|
broadcastEvent,
|
|
|
|
lastDetachedConnectedAt,
|
|
|
|
addEventHandler,
|
|
|
|
deleteEventHandler,
|
|
|
|
} = useDetachContext()
|
2021-11-30 09:54:14 -05:00
|
|
|
|
2023-01-09 09:33:43 -05:00
|
|
|
const eventName: Message['event'] = `state-${key}`
|
2021-11-30 09:54:14 -05:00
|
|
|
|
2022-03-31 07:22:36 -04:00
|
|
|
// lastDetachedConnectedAt is added as a dependency in order to re-broadcast
|
|
|
|
// all states when a new detached tab connects
|
2021-11-30 09:54:14 -05:00
|
|
|
useEffect(() => {
|
|
|
|
if (role === senderRole) {
|
|
|
|
broadcastEvent(eventName, { value })
|
|
|
|
}
|
2022-03-31 07:22:36 -04:00
|
|
|
}, [
|
|
|
|
role,
|
|
|
|
senderRole,
|
|
|
|
eventName,
|
|
|
|
value,
|
|
|
|
broadcastEvent,
|
|
|
|
lastDetachedConnectedAt,
|
|
|
|
])
|
2021-11-30 09:54:14 -05:00
|
|
|
|
|
|
|
const handleStateEvent = useCallback(
|
2023-01-09 09:33:43 -05:00
|
|
|
(message: Message) => {
|
2021-11-30 09:54:14 -05:00
|
|
|
if (message.event !== eventName) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (role !== targetRole) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (debugPdfDetach) {
|
|
|
|
console.log(`Set ${message.data.value} for ${eventName}`)
|
|
|
|
}
|
|
|
|
setValue(message.data.value)
|
|
|
|
},
|
|
|
|
[role, targetRole, eventName, setValue]
|
|
|
|
)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
addEventHandler(handleStateEvent)
|
|
|
|
return () => deleteEventHandler(handleStateEvent)
|
|
|
|
}, [addEventHandler, deleteEventHandler, handleStateEvent])
|
|
|
|
|
|
|
|
return [value, setValue]
|
|
|
|
}
|
2023-01-09 09:33:43 -05:00
|
|
|
|
|
|
|
export default useDetachState
|