import { useState , useEffect , useRef , useMemo } from 'react' ; import memoizeOne from 'memoize-one' ; import { useAdapter } from '../adapter/CallAdapterProvider' ; import { CallAdapterState } from '../adapter/CallAdapter' ; import { CallErrors , CallState , CallClientState , DeviceManagerState } from '@internal/calling-stateful-client' ; import { CommunicationIdentifierKind } from '@azure/communication-common' ; private export const useAdaptedSelector = < SelectorT extends ( state : CallClientState , props : any ) => any > ( selector , selectorProps ? ) : ReturnType < SelectorT > => { return useSelectorWithAdaptation ( selector , adaptCompositeState , selectorProps ) ; } ; private export const useSelectorWithAdaptation = < SelectorT extends ( state : ReturnType < AdaptFuncT > , props : any ) => any , AdaptFuncT extends ( state : CallAdapterState ) => any > ( selector , adaptState , selectorProps ? ) : ReturnType < SelectorT > => { const adapter = useAdapter ( ) ; const mounted = useRef ( false ) ; useEffect ( ( ) => { mounted . current = true ; return ( ) => { mounted . current = false ; } ; } ) ; const callId = adapter . getState ( ) . call ?. id ; const callConfigProps = useMemo ( ( ) => ( { callId } ) , [ callId ] ) ; const [ props , setProps ] = useState ( selector ( adaptState ( adapter . getState ( ) ) , selectorProps ?? callConfigProps ) ) ; const propRef = useRef ( props ) ; propRef . current = props ; useEffect ( ( ) => { const onStateChange = ( state ) : void => { if ( ! mounted . current ) { return ; } const newProps = selector ( adaptState ( state ) , selectorProps ?? callConfigProps ) ; if ( propRef . current !== newProps ) { setProps ( newProps ) ; } } ; adapter . onStateChange ( onStateChange ) ; return ( ) => { adapter . offStateChange ( onStateChange ) ; } ; } , [ adaptState , adapter , selector , selectorProps , callConfigProps ] ) ; return props ; } ; const memoizeState = memoizeOne ( ( userId , deviceManager , calls , latestErrors , displayName ? ) : CallClientState => ( { userId , incomingCalls : { } , incomingCallsEnded : { } , callsEnded : { } , deviceManager , callAgent : { displayName } , calls , latestErrors } ) ) ; const memoizeCalls = memoizeOne ( ( call ? ) : { [ key ] : CallState ; } => ( call ? { [ call . id ] : call } : { } ) ) ; const adaptCompositeState = ( compositeState ) : CallClientState => { return memoizeState ( compositeState . userId , compositeState . devices , memoizeCalls ( compositeState . call ) , compositeState . latestErrors as CallErrors , compositeState . displayName ) ; } ;