-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathSendFailed.tsx
More file actions
75 lines (60 loc) · 2.81 KB
/
SendFailed.tsx
File metadata and controls
75 lines (60 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { hooks } from 'botframework-webchat-api';
import { isPresentational } from 'botframework-webchat-core/internal';
import { memo, useMemo } from 'react';
import usePrevious from '../../hooks/internal/usePrevious';
import { useLiveRegion } from '../../providers/LiveRegionTwin';
import { SEND_FAILED } from '../../types/internal/SendStatus';
const { useGetActivityByKey, useLocalizer, useSendStatusByActivityKey } = hooks;
/**
* React component to on-demand narrate "Failed to send message" at the end of the live region.
*
* We cannot narrate "failed to send message" next to the activity. At the time when the activity is being sent,
* the activity is also queued to the screen reader. And at that moment, we not yet know if the activity can be sent or not.
*
* We only know when the activity was failed to send at a later time.
*
* Thus, we need to use a live region "footnote" to indicate the message was failed to send.
*/
const LiveRegionSendFailed = () => {
const [sendStatusByActivityKey] = useSendStatusByActivityKey();
const getActivityByKey = useGetActivityByKey();
const localize = useLocalizer();
/**
* List of keys of outgoing and non-presentational activities that are failed to send.
*
* Activities which are presentational, such as `event` or `typing`, are ignored to reduce confusions.
* "Failed to send message" should not be narrated for presentational activities.
*/
const activityKeysOfSendFailed = useMemo<Set<string>>(
() =>
Array.from(sendStatusByActivityKey).reduce((activityKeysOfSendFailed, [key, sendStatus]) => {
if (sendStatus === SEND_FAILED) {
const activity = getActivityByKey(key);
if (activity && !isPresentational(activity)) {
activityKeysOfSendFailed.add(key);
}
}
return activityKeysOfSendFailed;
}, new Set<string>()),
[getActivityByKey, sendStatusByActivityKey]
);
/** Returns localized "Failed to send message." */
const liveRegionSendFailedAlt = localize('TRANSCRIPT_LIVE_REGION_SEND_FAILED_ALT');
const prevActivityKeysOfSendFailed = usePrevious(activityKeysOfSendFailed);
/** True, if one or more non-presentational activities start appears as "send failed", otherwise, false. */
const hasNewSendFailed = useMemo<boolean>(() => {
if (activityKeysOfSendFailed === prevActivityKeysOfSendFailed) {
return false;
}
for (const key of activityKeysOfSendFailed.keys()) {
if (!prevActivityKeysOfSendFailed.has(key)) {
return true;
}
}
return false;
}, [activityKeysOfSendFailed, prevActivityKeysOfSendFailed]);
useLiveRegion(() => hasNewSendFailed && liveRegionSendFailedAlt, [hasNewSendFailed, liveRegionSendFailedAlt]);
return null;
};
LiveRegionSendFailed.displayName = 'LiveRegionSendFailed';
export default memo(LiveRegionSendFailed);