1- import React , { useEffect , useMemo , useRef , type ReactNode } from 'react' ;
21import { querySendStatusFromOutgoingActivity } from 'botframework-webchat-core/activity' ;
2+ import { isPresentational } from 'botframework-webchat-core/internal' ;
3+ import React , { useEffect , useMemo , useRef , type ReactNode } from 'react' ;
34
4- import { useActivities , usePonyfill } from '../../hooks/index' ;
5+ import { useActivities , useGetActivityByKey , usePonyfill } from '../../hooks/index' ;
56import useForceRender from '../../hooks/internal/useForceRender' ;
67import useGetSendTimeoutForActivity from '../../hooks/useGetSendTimeoutForActivity' ;
78import type { SendStatus } from '../../types/SendStatus' ;
@@ -10,15 +11,18 @@ import useGetKeyByActivity from '../ActivityKeyer/useGetKeyByActivity';
1011import type { ActivitySendStatusContextType } from './private/Context' ;
1112import ActivitySendStatusContext from './private/Context' ;
1213import isMapEqual from './private/isMapEqual' ;
14+ import type { ActivitySendStatusSubContextType } from './private/SubContext' ;
15+ import ActivitySendStatusSubContext from './private/SubContext' ;
1316
1417// Magic numbers for `expiryByActivityKey`.
1518const EXPIRY_SEND_FAILED = - Infinity ;
1619const EXPIRY_SENT = Infinity ;
1720
1821const ActivitySendStatusComposer = ( { children } : Readonly < { children ?: ReactNode | undefined } > ) => {
19- const [ activities ] = useActivities ( ) ;
2022 const [ { clearTimeout, Date, setTimeout } ] = usePonyfill ( ) ;
23+ const [ activities ] = useActivities ( ) ;
2124 const forceRender = useForceRender ( ) ;
25+ const getActivityByKey = useGetActivityByKey ( ) ;
2226 const getKeyByActivity = useGetKeyByActivity ( ) ;
2327 const getSendTimeoutForActivity = useGetSendTimeoutForActivity ( ) ;
2428 const sendStatusByActivityKeyRef = useRef < ReadonlyMap < string , SendStatus > > ( Object . freeze ( new Map ( ) ) ) ;
@@ -93,11 +97,30 @@ const ActivitySendStatusComposer = ({ children }: Readonly<{ children?: ReactNod
9397 [ sendStatusByActivityKey ]
9498 ) ;
9599
100+ const isSendingState = useMemo < readonly [ boolean ] > (
101+ ( ) =>
102+ Object . freeze ( [
103+ sendStatusByActivityKey . entries ( ) . some ( ( [ activityKey , status ] ) => {
104+ if ( status === 'sending' ) {
105+ const activity = getActivityByKey ( activityKey ) ;
106+
107+ return activity && ! isPresentational ( activity ) ;
108+ }
109+ } )
110+ ] ) ,
111+ [ getActivityByKey , sendStatusByActivityKey ]
112+ ) ;
113+
96114 const context = useMemo < ActivitySendStatusContextType > (
97- ( ) => ( { sendStatusByActivityKeyState } ) ,
115+ ( ) => Object . freeze ( { sendStatusByActivityKeyState } ) ,
98116 [ sendStatusByActivityKeyState ]
99117 ) ;
100118
119+ const subContext = useMemo < ActivitySendStatusSubContextType > (
120+ ( ) => Object . freeze ( { isSendingState } ) ,
121+ [ isSendingState ]
122+ ) ;
123+
101124 // Finds the closest expiry. This is the time we should recompute `sendStatusByActivityKey`.
102125 const nextExpiry = Array . from ( expiryByActivityKey . values ( ) )
103126 // Ignores activities which are already marked as `"send failed"`, because the magic number its `-Infinity`.
@@ -120,7 +143,11 @@ const ActivitySendStatusComposer = ({ children }: Readonly<{ children?: ReactNod
120143 }
121144 } , [ clearTimeout , Date , forceRender , nextExpiry , setTimeout ] ) ;
122145
123- return < ActivitySendStatusContext . Provider value = { context } > { children } </ ActivitySendStatusContext . Provider > ;
146+ return (
147+ < ActivitySendStatusContext . Provider value = { context } >
148+ < ActivitySendStatusSubContext . Provider value = { subContext } > { children } </ ActivitySendStatusSubContext . Provider >
149+ </ ActivitySendStatusContext . Provider >
150+ ) ;
124151} ;
125152
126153export default ActivitySendStatusComposer ;
0 commit comments