11import { type IMessage , type ISubscription , type IRoom , isE2EEMessage } from '@rocket.chat/core-typings' ;
2+ import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts' ;
23import { usePermission , useRouter , useUser } from '@rocket.chat/ui-contexts' ;
3- import { useCallback } from 'react' ;
4+ import { useCallback , useMemo } from 'react' ;
5+ import { useShallow } from 'zustand/shallow' ;
46
57import { Rooms , Subscriptions } from '../../../../app/models/client' ;
68import type { MessageActionConfig } from '../../../../app/ui-utils/client/lib/MessageAction' ;
79import { useEmbeddedLayout } from '../../../hooks/useEmbeddedLayout' ;
8- import { useReactiveValue } from '../../../hooks/useReactiveValue' ;
910import { roomCoordinator } from '../../../lib/rooms/roomCoordinator' ;
1011
1112export const useReplyInDMAction = (
@@ -18,25 +19,36 @@ export const useReplyInDMAction = (
1819 const canCreateDM = usePermission ( 'create-d' ) ;
1920 const isLayoutEmbedded = useEmbeddedLayout ( ) ;
2021
21- const condition = useReactiveValue (
22- useCallback ( ( ) => {
23- if ( ! subscription || room . t === 'd' || room . t === 'l' || isLayoutEmbedded ) {
24- return false ;
25- }
22+ const roomPredicate = useCallback (
23+ ( record : IRoom ) : boolean => {
24+ const ids = [ user ?. _id , message . u . _id ] . sort ( ) . join ( '' ) ;
25+ return ids . includes ( record . _id ) ;
26+ } ,
27+ [ message . u . _id , user ] ,
28+ ) ;
2629
27- // Check if we already have a DM started with the message user (not ourselves) or we can start one
28- if ( ! ! user && user . _id !== message . u . _id && ! canCreateDM ) {
29- const dmRoom = Rooms . findOne ( { _id : [ user . _id , message . u . _id ] . sort ( ) . join ( '' ) } ) ;
30- if ( ! dmRoom || ! Subscriptions . findOne ( { 'rid' : dmRoom . _id , 'u._id' : user . _id } ) ) {
31- return false ;
32- }
33- }
30+ const shouldFindRoom = useMemo ( ( ) => ! ! user && canCreateDM && user . _id !== message . u . _id , [ canCreateDM , message . u . _id , user ] ) ;
31+ const dmRoom = Rooms . use ( useShallow ( ( state ) => ( shouldFindRoom ? state . find ( roomPredicate ) : undefined ) ) ) ;
3432
35- return true ;
36- } , [ canCreateDM , isLayoutEmbedded , message . u . _id , room . t , subscription , user ] ) ,
33+ const subsPredicate = useCallback (
34+ ( record : SubscriptionWithRoom ) => record . rid === dmRoom ?. _id || record . u . _id === user ?. _id ,
35+ [ dmRoom , user ?. _id ] ,
3736 ) ;
37+ const dmSubs = Subscriptions . use ( useShallow ( ( state ) => state . find ( subsPredicate ) ) ) ;
38+
39+ const canReplyInDM = useMemo ( ( ) => {
40+ if ( ! subscription || room . t === 'd' || room . t === 'l' || isLayoutEmbedded ) {
41+ return false ;
42+ }
43+ if ( ! ! user && user . _id !== message . u . _id && canCreateDM ) {
44+ if ( ! dmRoom || ! dmSubs ) {
45+ return false ;
46+ }
47+ }
48+ return true ;
49+ } , [ canCreateDM , dmRoom , dmSubs , isLayoutEmbedded , message . u . _id , room . t , subscription , user ] ) ;
3850
39- if ( ! condition ) {
51+ if ( ! canReplyInDM ) {
4052 return null ;
4153 }
4254
0 commit comments