UNPKG

@azure/communication-react

Version:

React library for building modern communication user experiences utilizing Azure Communication Services

76 lines 3.44 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { useState, useEffect, useRef, useMemo } from 'react'; import { useAdapter } from '../adapter/ChatAdapterProvider'; import memoizeOne from 'memoize-one'; /** * @private */ export const useAdaptedSelector = (selector, selectorProps) => { return useSelectorWithAdaptation(selector, adaptCompositeState, selectorProps); }; /** * @private */ export const useSelectorWithAdaptation = (selector, adaptState, selectorProps) => { const adapter = useAdapter(); // Keeps track of whether the current component is mounted or not. If it has unmounted, make sure we do not modify the // state or it will cause React warnings in the console. https://skype.visualstudio.com/SPOOL/_workitems/edit/2453212 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 !== null && selectorProps !== void 0 ? selectorProps : threadConfigProps)); const propRef = useRef(props); propRef.current = props; useEffect(() => { const onStateChange = (state) => { if (!mounted.current) { return; } const newProps = selector(adaptState(state), selectorProps !== null && selectorProps !== void 0 ? 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) => { return memoizeState(compositeState.userId, compositeState.displayName, memoizeThreads(compositeState.thread), // This is an unsafe type expansion. // compositeState.latestErrors can contain properties that are not valid in ChatErrors. // // But there is no way to check for valid property names at runtime: // - The set of valid property names is built from types in the @azure/communication-chat. // Thus we don't have a literal array of allowed strings at runtime. // - Due to minification / uglification, the property names from the objects at runtime can't be used // to compare against permissible values inferred from the types. // // This is not a huge problem -- it simply means that our adapted selector will include some extra operations // that are unknown to the UI component and data binding libraries. Generic handling of the errors (e.g., // just displaying them in some UI surface) will continue to work for these operations. Handling of // specific operations (e.g., acting on errors related to permission issues) will ignore these operations. compositeState.latestErrors); }; //# sourceMappingURL=useAdaptedSelector.js.map