diff --git a/app/ui/client/lib/UserCard.js b/app/ui/client/lib/UserCard.js index 75123493e0db3..4620f7eb1ab6d 100644 --- a/app/ui/client/lib/UserCard.js +++ b/app/ui/client/lib/UserCard.js @@ -18,8 +18,9 @@ export const closeUserCard = () => { if (!dom) { return; } - unregister(); - unregister = undefined; + Tracker.afterFlush(() => { + unregister = unregister && unregister(); + }); }; const props = () => { diff --git a/client/channel/UserCard/index.js b/client/channel/UserCard/index.js index e5cf96b0f8de6..05697ab71eca5 100644 --- a/client/channel/UserCard/index.js +++ b/client/channel/UserCard/index.js @@ -1,5 +1,6 @@ -import React, { useMemo, useRef, useCallback } from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; import { PositionAnimated, AnimatedVisibility, Menu, Option } from '@rocket.chat/fuselage'; +import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../hooks/useEndpointDataExperimental'; import { useSetting } from '../../contexts/SettingsContext'; @@ -9,6 +10,21 @@ import { Backdrop } from '../../components/basic/Backdrop'; import * as UserStatus from '../../components/basic/UserStatus'; import { LocalTime } from '../../components/basic/UTCClock'; import { useUserInfoActions, useUserInfoActionsSpread } from '../hooks/useUserInfoActions'; +import { useCurrentRoute } from '../../contexts/RouterContext'; + +export const useComponentDidUpdate = ( + effect, + dependencies = [], +) => { + const hasMounted = useRef(false); + useEffect(() => { + if (!hasMounted.current) { + hasMounted.current = true; + return; + } + effect(); + }, dependencies); +}; const UserCardWithData = ({ username, onClose, target, open, rid }) => { const ref = useRef(target); @@ -23,6 +39,12 @@ const UserCardWithData = ({ username, onClose, target, open, rid }) => { ref.current = target; + const [route, params] = useCurrentRoute(); + + useComponentDidUpdate(() => { + onClose && onClose(); + }, [route, JSON.stringify(params), onClose]); + const user = useMemo(() => { const loading = state === ENDPOINT_STATES.LOADING; const defaultValue = loading ? undefined : null; @@ -55,13 +77,10 @@ const UserCardWithData = ({ username, onClose, target, open, rid }) => { }; }, [data, username, showRealNames, state]); - const handleOpen = useCallback( - (e) => { - open && open(e); - onClose && onClose(); - }, - [open, onClose], - ); + const handleOpen = useMutableCallback((e) => { + open && open(e); + onClose && onClose(); + }); const { actions: actionsDefinition, menu: menuOptions } = useUserInfoActionsSpread(useUserInfoActions(user, rid)); diff --git a/client/reactAdapters.js b/client/reactAdapters.js index 078afb7a2a7d5..2c7b129e2ed85 100644 --- a/client/reactAdapters.js +++ b/client/reactAdapters.js @@ -1,5 +1,6 @@ import { Blaze } from 'meteor/blaze'; import { HTML } from 'meteor/htmljs'; +import { Random } from 'meteor/random'; import { BlazeLayout } from 'meteor/kadira:blaze-layout'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { ReactiveVar } from 'meteor/reactive-var'; @@ -25,6 +26,7 @@ const mountRoot = async () => { ] = await Promise.all([ import('react'), import('react-dom'), + import('@rocket.chat/fuselage-hooks'), ]); const LazyMeteorProvider = lazy(() => import('./providers/MeteorProvider')); @@ -73,7 +75,7 @@ export const registerPortal = (key, portal) => { mountRoot(); } - portalsMap.set(key, { portal, key: Date.now() }); + portalsMap.set(key, { portal, key: Random.id() }); invalidatePortals(); return () => unregisterPortal(key); };