import { ChatClientState , ChatErrors , ChatThreadClientState } from '@internal/chat-stateful-client' ; import { useState , useEffect , useRef , useMemo } from 'react' ; import { ChatAdapterState } from '../adapter/ChatAdapter' ; import { useAdapter } from '../adapter/ChatAdapterProvider' ; import memoizeOne from 'memoize-one' ; import { CommunicationIdentifierKind } from '@azure/communication-common' ; private export const useAdaptedSelector = < SelectorT extends ( state : ChatClientState , 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 : ChatAdapterState ) => any > ( selector , adaptState , selectorProps ? ) : ReturnType < SelectorT > => { const adapter = useAdapter ( ) ; const mounted = useRef ( false ) ; useEffect ( ( ) => { mounted . current = true ; return ( ) => { mounted . current = false ; } ; } ) ; const threadId = adapter . getState ( ) . thread . threadId ; const threadConfigProps = useMemo ( ( ) => ( { threadId } ) , [ threadId ] ) ; const [ props , setProps ] = useState ( selector ( adaptState ( adapter . getState ( ) ) , selectorProps ?? threadConfigProps ) ) ; const propRef = useRef ( props ) ; propRef . current = props ; useEffect ( ( ) => { const onStateChange = ( state ) : void => { if ( ! mounted . current ) { return ; } const newProps = selector ( adaptState ( state ) , selectorProps ?? threadConfigProps ) ; if ( propRef . current !== newProps ) { setProps ( newProps ) ; } } ; adapter . onStateChange ( onStateChange ) ; return ( ) => { adapter . offStateChange ( onStateChange ) ; } ; } , [ adaptState , adapter , selector , selectorProps , threadConfigProps ] ) ; return props ; } ; const memoizeState = memoizeOne ( ( userId , displayName , threads , latestErrors ) => ( { userId , displayName , threads , latestErrors } ) ) ; const memoizeThreads = memoizeOne ( ( thread ) => ( { [ thread . threadId ] : thread } ) ) ; const adaptCompositeState = ( compositeState ) : ChatClientState => { return memoizeState ( compositeState . userId , compositeState . displayName , memoizeThreads ( compositeState . thread ) , compositeState . latestErrors as ChatErrors ) ; } ;