UNPKG

@daily-co/daily-react

Version:

Daily React makes it easier to integrate [@daily-co/daily-js](https://www.npmjs.com/package/@daily-co/daily-js) in React applications.

106 lines (95 loc) 3.18 kB
import { DailyEvent, DailyEventObject } from '@daily-co/daily-js'; import throttle from 'lodash.throttle'; import { useCallback, useContext, useDebugValue, useEffect, useMemo, useRef, } from 'react'; import { DailyEventContext } from '../DailyEventContext'; import { getPriorityUnique, getUnique, useDailyEvent } from './useDailyEvent'; type EnsureArray<T> = T extends DailyEvent ? [T] : T; type EventObjectsFor<T> = EnsureArray<T> extends (infer U)[] ? U extends DailyEvent ? DailyEventObject<U> : never : never; type EventCallback<T extends DailyEvent | DailyEvent[]> = ( events: EventObjectsFor<T>[] ) => void; /** * Sets up a throttled daily event listener using [on](https://docs.daily.co/reference/daily-js/instance-methods/on) method. * When this hook is unmounted the event listener is unregistered using [off](https://docs.daily.co/reference/daily-js/instance-methods/off). * * In comparison to useDailyEvent the callback passed here will be called with an array of event objects. * * You can pass an array of DailyEvents to register multiple daily events with a single callback handler. * The events returned in the callback parameter are guaranteed to be in the same order as they were emitted. * * @param ev The DailyEvent to register or an array of DailyEvent to register. * @param callback A memoized callback reference to run when throttled events are emitted. * @param throttleTimeout The minimum waiting time until the callback is called again. Default: 500 */ export const useThrottledDailyEvent = <T extends DailyEvent>( ev: T | T[], callback: EventCallback<EnsureArray<T>>, throttleTimeout = 500, INTERNAL_priority = false ) => { const { off, on } = useContext(DailyEventContext); const eventId = useMemo(() => { if (Array.isArray(ev)) return ev.reduce<Record<string, number>>((r, e) => { r[e] = INTERNAL_priority ? getPriorityUnique() : getUnique(); return r; }, {}); return { [ev]: INTERNAL_priority ? getPriorityUnique() : getUnique() }; }, [ev, INTERNAL_priority]); const throttledEvents = useRef<EventObjectsFor<T>[]>([]); useDailyEvent( 'call-instance-destroyed', useCallback(() => { throttledEvents.current.length = 0; }, []) ); const emitEvents = useMemo( () => throttle( () => { if (throttledEvents.current.length === 0) return; callback(throttledEvents.current); throttledEvents.current.length = 0; }, throttleTimeout, { trailing: true, } ), [callback, throttleTimeout] ); useEffect(() => { if (!ev) return; const addEvent = (ev: DailyEventObject) => { throttledEvents.current.push(ev); emitEvents(); }; if (Array.isArray(ev)) { ev.forEach((e) => on(e, addEvent, eventId[e])); } else { on(ev, addEvent, eventId[ev]); } return () => { if (Array.isArray(ev)) { ev.forEach((e) => off(e, eventId[e])); } else { off(ev, eventId[ev]); } }; }, [emitEvents, ev, eventId, off, on]); useDebugValue({ event: ev, eventId, }); };