UNPKG

communication-react-19

Version:

React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)

81 lines 3.95 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. /* eslint-disable @typescript-eslint/no-explicit-any */ import { useState, useEffect, useRef } from 'react'; import memoizeOne from 'memoize-one'; import { useAdapter } from '../adapter/CallAdapterProvider'; /** * @private */ export const useAdaptedSelector = (selector, selectorProps) => { return useSelectorWithAdaptation(selector, adaptCompositeState, selectorProps); }; /** * @private */ export const useSelectorWithAdaptation = (selector, adaptState, selectorProps) => { var _a; 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 callId = (_a = adapter.getState().call) === null || _a === void 0 ? void 0 : _a.id; const [props, setProps] = useState(selector(adaptState(adapter.getState()), selectorProps !== null && selectorProps !== void 0 ? selectorProps : { callId })); const propRef = useRef(props); propRef.current = props; useEffect(() => { const onStateChange = (state) => { var _a; if (!mounted.current) { return; } const newProps = selector(adaptState(state), selectorProps !== null && selectorProps !== void 0 ? selectorProps : { callId: (_a = state.call) === null || _a === void 0 ? void 0 : _a.id }); if (propRef.current !== newProps) { setProps(newProps); } }; adapter.onStateChange(onStateChange); return () => { adapter.offStateChange(onStateChange); }; }, [adaptState, adapter, selector, selectorProps]); return props; }; const memoizeState = memoizeOne((userId, deviceManager, calls, latestErrors, latestNotifications, displayName, alternateCallerId, environmentInfo) => ({ userId, incomingCalls: {}, incomingCallsEnded: {}, callsEnded: {}, deviceManager, callAgent: { displayName }, calls, latestErrors, latestNotifications: latestNotifications !== null && latestNotifications !== void 0 ? latestNotifications : {}, alternateCallerId, environmentInfo })); const memoizeCalls = memoizeOne((call) => (call ? { [call.id]: call } : {})); const adaptCompositeState = (compositeState) => { return memoizeState(compositeState.userId, compositeState.devices, memoizeCalls(compositeState.call), // This is an unsafe type expansion. // compositeState.latestErrors can contain properties that are not valid in CallErrors. // // 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-calling. // 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, compositeState.latestNotifications, compositeState.displayName, compositeState.alternateCallerId, compositeState.environmentInfo); }; //# sourceMappingURL=useAdaptedSelector.js.map